The following commit has been merged in the master branch:
commit 46b688e4824f00842568b517b119eec34a5f7286
Author: Raphaël Hertzog <hert...@debian.org>
Date:   Thu Jul 14 20:31:33 2011 +0200

    dpkg-source: implement --commit and fail with unrecorded changes
    
    Formats "2.0" and "3.0 (quilt)" now fail by default in presence of
    changes to upstream files that are not managed by their respective patch
    system. The user is invited to run dpkg-source --commit if he
    wants to keep the changes.
    
    This will avoid that maintainers upload packages with unexpected changes.
    The old behaviour can be kept with the option --auto-commit. The option
    --abort-on-upstream-changes is now useless with formats "2.0" and "3.0
    (quilt)" except to cancel the effect of a former --auto-commit.
    
    See http://lists.debian.org/20110529085303.ga17...@rivendell.home.ouaza.com
    for the discussion that enterined this change.

diff --git a/debian/changelog b/debian/changelog
index 18a3793..61dbeef 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -87,6 +87,12 @@ dpkg (1.16.1) UNRELEASED; urgency=low
     under root. Closes: #634961
   * Change merge conflict separators created by dpkg-mergechangelogs to match
     the usual norm of being composed of 7 characters. LP: #815700
+  * With source format 2.0 and 3.0 (quilt), dpkg-source now fails by default
+    when upstream changes have not been recorded in a quilt patch. The new
+    --commit operation can be used to properly record the changes before-hand.
+    LP: #797839
+    And it fails before installing the automatic patch in debian/patches/
+    Closes: #615899
 
   [ Guillem Jover ]
   * Install deb-src-control(5) man pages in dpkg-dev. Closes: #620520
diff --git a/man/dpkg-source.1 b/man/dpkg-source.1
index 025f7db..fb6f377 100644
--- a/man/dpkg-source.1
+++ b/man/dpkg-source.1
@@ -1,5 +1,5 @@
 .\" Authors: Ian Jackson, Raphaël Hertzog
-.TH dpkg\-source 1 "2011-07-04" "Debian Project" "dpkg utilities"
+.TH dpkg\-source 1 "2011-07-12" "Debian Project" "dpkg utilities"
 .SH NAME
 dpkg\-source \- Debian source package (.dsc) manipulation tool
 .
@@ -88,6 +88,12 @@ all source formats implement something in this hook, and 
those that do
 usually use it to undo what \fB\-\-before\-build\fP has done.
 
 .TP
+.RI "\fB\-\-commit\fP [" directory "] ..."
+Record changes in the source tree unpacked in \fIdirectory\fP. This
+command can take supplementary parameters depending on the source format.
+It will error out for formats where this operation doesn't mean anything.
+
+.TP
 .BR \-h ", " \-\-help
 Show the usage message and exit.
 .TP
@@ -437,7 +443,9 @@ debian directory is copied over in the temporary directory, 
and all
 patches except the automatic patch (\fBdebian-changes-\fP\fIversion\fP
 or \fBdebian-changes\fP, depending on \fB\-\-single\-debian\-patch\fP) are
 applied. The temporary directory is compared to the source package
-directory and the diff (if non-empty) is stored in the automatic patch.
+directory. When the diff is non-empty, the build fails unless
+\fB\-\-single\-debian\-patch\fP or \fB\-\-auto\-commit\fP
+has been used. In the latter case, the diff is stored in the automatic patch.
 If the automatic patch is created/deleted, it's added/removed from the
 series file and from the quilt metadata.
 
@@ -466,6 +474,20 @@ unapplied patches (they are listed in the \fBseries\fP 
file but not in
 applied without errors, it will apply them all. The option
 \fB\-\-no\-preparation\fP can be used to disable this
 behavior.
+
+.PP
+.B Recording changes
+.TP
+.RI "\fB\-\-commit\fP [" directory "] [" patch-name "] [" patch-file ]
+Generates a patch corresponding to the local changes that are not managed
+by the quilt patch system and integrates it in the patch system under
+the name \fIpatch-name\fP. If the name is missing, it will be asked
+interactively. If \fIpatch-file\fP is given, it is used as the patch
+corresponding to the local changes to integrate. This is mainly useful
+after a build failure that pre-generated this file. Once integrated, an
+editor is launched so that you can edit the meta-information in the patch
+header.
+
 .PP
 .B Build options
 .TP
@@ -523,6 +545,10 @@ can be used to ensure that all changes were properly 
recorded in separate
 quilt patches prior to the source package build. This option is not
 allowed in \fBdebian/source/options\fP but can be used in
 \fBdebian/source/local\-options\fP.
+.TP
+.B \-\-auto\-commit
+The process doesn't fail if an automatic patch has been generated, instead
+it's immediately recorded in the quilt series.
 
 .PP
 .B Extract options
@@ -704,7 +730,7 @@ Copyright \(co 1995-1996 Ian Jackson
 .br
 Copyright \(co 2000 Wichert Akkerman
 .br
-Copyright \(co 2008-2010 Rapha\[:e]l Hertzog
+Copyright \(co 2008-2011 Rapha\[:e]l Hertzog
 .sp
 This is free software; see the GNU General Public Licence version 2 or later
 for copying conditions. There is NO WARRANTY.
diff --git a/scripts/Dpkg/Source/Package.pm b/scripts/Dpkg/Source/Package.pm
index 21089a2..94e6b8f 100644
--- a/scripts/Dpkg/Source/Package.pm
+++ b/scripts/Dpkg/Source/Package.pm
@@ -1,4 +1,4 @@
-# Copyright © 2008 Raphaël Hertzog <hert...@debian.org>
+# Copyright © 2008-2011 Raphaël Hertzog <hert...@debian.org>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -512,6 +512,12 @@ sub add_file {
                                            use_files_for_md5 => 1);
 }
 
+sub commit {
+    my ($self, $dir) = @_;
+    info(_g("'%s' is not supported by the source format '%s'"),
+         "dpkg-source --commit", $self->{'fields'}{'Format'});
+}
+
 sub write_dsc {
     my ($self, %opts) = @_;
     my $fields = $self->{'fields'};
diff --git a/scripts/Dpkg/Source/Package/V2.pm 
b/scripts/Dpkg/Source/Package/V2.pm
index e058e35..b8c5d27 100644
--- a/scripts/Dpkg/Source/Package/V2.pm
+++ b/scripts/Dpkg/Source/Package/V2.pm
@@ -63,8 +63,8 @@ sub init_options {
         unless exists $self->{'options'}{'skip_debianization'};
     $self->{'options'}{'create_empty_orig'} = 0
         unless exists $self->{'options'}{'create_empty_orig'};
-    $self->{'options'}{'abort_on_upstream_changes'} = 0
-        unless exists $self->{'options'}{'abort_on_upstream_changes'};
+    $self->{'options'}{'auto_commit'} = 0
+        unless exists $self->{'options'}{'auto_commit'};
 }
 
 sub parse_cmdline_option {
@@ -94,7 +94,10 @@ sub parse_cmdline_option {
         $self->{'options'}{'create_empty_orig'} = 1;
         return 1;
     } elsif ($opt =~ /^--abort-on-upstream-changes$/) {
-        $self->{'options'}{'abort_on_upstream_changes'} = 1;
+        $self->{'options'}{'auto_commit'} = 0;
+        return 1;
+    } elsif ($opt =~ /^--auto-commit$/) {
+        $self->{'options'}{'auto_commit'} = 1;
         return 1;
     }
     return 0;
@@ -340,8 +343,10 @@ sub generate_patch {
     error(_g("no upstream tarball found at %s"),
           $self->upstream_tarball_template()) unless $tarfile;
 
-    info(_g("building %s using existing %s"),
-         $self->{'fields'}{'Source'}, "@origtarballs");
+    if ($opts{'usage'} eq "build") {
+        info(_g("building %s using existing %s"),
+             $self->{'fields'}{'Source'}, "@origtarballs");
+    }
 
     # Unpack a second copy for comparison
     my $tmp = tempdir("$dirname.orig.XXXXXX", DIR => $updir);
@@ -368,7 +373,7 @@ sub generate_patch {
 
     # Create a patch
     my ($difffh, $tmpdiff) = tempfile($self->get_basename(1) . ".diff.XXXXXX",
-                                      DIR => $updir, UNLINK => 0);
+                                      DIR => File::Spec->tmpdir(), UNLINK => 
0);
     push @Dpkg::Exit::handlers, sub { unlink($tmpdiff) };
     my $diff = Dpkg::Source::Patch->new(filename => $tmpdiff,
                                         compression => "none");
@@ -496,15 +501,19 @@ sub do_build {
     my $tmpdiff = $self->generate_patch($dir, order_from => $autopatch,
                                         handle_binary => $handle_binary,
                                         usage => 'build');
+    unless (not -s $tmpdiff or $self->{'options'}{'single_debian_patch'}
+            or $self->{'options'}{'auto_commit'}) {
+        info(_g("you can integrate the local changes with %s"),
+             "dpkg-source --commit . '' $tmpdiff");
+        error(_g("aborting due to unexpected upstream changes, see %s"),
+              $tmpdiff);
+    }
     push @Dpkg::Exit::handlers, sub { unlink($tmpdiff) };
 
     # Install the diff as the new autopatch
     mkpath(File::Spec->catdir($dir, "debian", "patches"));
     $autopatch = $self->register_patch($dir, $tmpdiff,
                                        $self->get_autopatch_name());
-    if (-e $autopatch and $self->{'options'}{'abort_on_upstream_changes'}) {
-        error(_g("aborting due to --abort-on-upstream-changes"));
-    }
     info(_g("local changes have been recorded in a new patch: %s"), 
$autopatch);
     rmdir(File::Spec->catdir($dir, "debian", "patches")); # No check on purpose
     unlink($tmpdiff) || syserr(_g("cannot remove %s"), $tmpdiff);
@@ -597,5 +606,46 @@ sub register_patch {
     return $patch;
 }
 
+sub commit {
+    my ($self, $dir) = @_;
+    my ($patch_name, $tmpdiff) = @{$self->{'options'}{'ARGV'}};
+
+    sub bad_patch_name {
+        my ($dir, $patch_name) = @_;
+        return 1 if not defined($patch_name);
+        return 1 if not length($patch_name);
+        my $patch = File::Spec->catfile($dir, "debian", "patches", 
$patch_name);
+        if (-e $patch) {
+            warning(_g("cannot register changes in %s, this patch already 
exists"), $patch);
+            return 1;
+        }
+        return 0;
+    }
+
+    $self->prepare_build($dir);
+
+    unless ($tmpdiff && -e $tmpdiff) {
+        $tmpdiff = $self->generate_patch($dir, usage => "commit");
+    }
+    push @Dpkg::Exit::handlers, sub { unlink($tmpdiff) };
+    unless (-s $tmpdiff) {
+        unlink($tmpdiff) || syserr(_g("cannot remove %s"), $tmpdiff);
+        info(_g("there are no local changes to record"));
+        return;
+    }
+    while (bad_patch_name($dir, $patch_name)) {
+        # Ask the patch name interactively
+        print STDOUT _g("Enter the desired patch name: ");
+        chomp($patch_name = <STDIN>);
+        $patch_name =~ s/\s+/-/g;
+        $patch_name =~ s/\///g;
+    }
+    my $patch = $self->register_patch($dir, $tmpdiff, $patch_name);
+    system("sensible-editor", $patch);
+    unlink($tmpdiff) || syserr(_g("cannot remove %s"), $tmpdiff);
+    pop @Dpkg::Exit::handlers;
+    info(_g("local changes have been recorded in a new patch: %s"), $patch);
+}
+
 # vim:et:sw=4:ts=8
 1;
diff --git a/scripts/dpkg-source.pl b/scripts/dpkg-source.pl
index 6279fc1..1b90491 100755
--- a/scripts/dpkg-source.pl
+++ b/scripts/dpkg-source.pl
@@ -87,6 +87,8 @@ while (@ARGV && $ARGV[0] =~ m/^-/) {
         setopmode('-x');
     } elsif (m/^--(before|after)-build$/) {
         setopmode($_);
+    } elsif (m/^--commit$/) {
+        setopmode($_);
     } elsif (m/^--print-format$/) {
        setopmode('--print-format');
        report_options(info_fh => \*STDERR); # Avoid clutter on STDOUT
@@ -97,11 +99,14 @@ while (@ARGV && $ARGV[0] =~ m/^-/) {
 
 my $dir;
 if (defined($options{'opmode'}) &&
-    $options{'opmode'} =~ 
/^(-b|--print-format|--before-build|--after-build)$/) {
+    $options{'opmode'} =~ 
/^(-b|--print-format|--(before|after)-build|--commit)$/) {
     if (not scalar(@ARGV)) {
-       usageerr(_g("%s needs a directory"), $options{'opmode'});
+       usageerr(_g("%s needs a directory"), $options{'opmode'})
+           unless $1 eq "--commit";
+       $dir = ".";
+    } else {
+       $dir = File::Spec->catdir(shift(@ARGV));
     }
-    $dir = File::Spec->catdir(shift(@ARGV));
     stat($dir) || syserr(_g("cannot stat directory %s"), $dir);
     if (not -d $dir) {
        error(_g("directory argument %s is not a directory"), $dir);
@@ -206,10 +211,10 @@ while (@options) {
 }
 
 unless (defined($options{'opmode'})) {
-    usageerr(_g("need a command (-x, -b, --before-build, --after-build, 
--print-format)"));
+    usageerr(_g("need a command (-x, -b, --before-build, --after-build, 
--print-format, --commit)"));
 }
 
-if ($options{'opmode'} =~ /^(-b|--print-format|--(before|after)-build)$/) {
+if ($options{'opmode'} =~ 
/^(-b|--print-format|--(before|after)-build|--commit)$/) {
 
     $options{'ARGV'} = \@ARGV;
 
@@ -363,6 +368,9 @@ if ($options{'opmode'} =~ 
/^(-b|--print-format|--(before|after)-build)$/) {
     } elsif ($options{'opmode'} eq "--after-build") {
        $srcpkg->after_build($dir);
        exit(0);
+    } elsif ($options{'opmode'} eq "--commit") {
+       $srcpkg->commit($dir);
+       exit(0);
     }
 
     # Verify pre-requisites are met
@@ -466,7 +474,9 @@ Commands:
                            extract source package.
   -b <dir>                 build source package.
   --print-format <dir>     print the source format that would be
-                           used to build the source package.")
+                           used to build the source package.
+  --commit [<dir> [<patch-name>]]
+                           store upstream changes in a new patch.")
     . "\n\n" . _g(
 "Build options:
   -c<controlfile>          get control info from this file.

-- 
dpkg's main repository


-- 
To UNSUBSCRIBE, email to debian-dpkg-cvs-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to