chiark / gitweb /
dgit, git-debrebase: Properly make patches with nasty .gitignores.
[dgit.git] / git-debrebase
index 3de0aa9f1c1f62c569634e832b861e0f0dba0fc1..04befff5484477c888825954b20ae53c760ce983 100755 (executable)
@@ -19,6 +19,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 END { $? = $Debian::Dgit::ExitStatus::desired // -1; };
+use Debian::Dgit::GDR;
 use Debian::Dgit::ExitStatus;
 
 use strict;
@@ -33,6 +34,7 @@ use Data::Dumper;
 use Getopt::Long qw(:config posix_default gnu_compat bundling);
 use Dpkg::Version;
 use File::FnMatch qw(:fnmatch);
+use File::Copy;
 
 our ($opt_force, $opt_noop_ok, @opt_anchors);
 our ($opt_defaultcmd_interactive);
@@ -116,7 +118,7 @@ sub run_deferred_updates ($) {
 
     confess 'dangerous internal error' unless all_snags_summarised();
 
-    my @upd_cmd = (@git, qw(update-ref --stdin -m), "debrebase: $mrest");
+    my @upd_cmd = (git_update_ref_cmd "debrebase: $mrest", qw(--stdin));
     debugcmd '>|', @upd_cmd;
     open U, "|-", @upd_cmd or die $!;
     foreach (@deferred_updates) {
@@ -1018,7 +1020,7 @@ sub record_ffq_prev_deferred () {
        }
        return if $invert;
        my $lrval = git_get_ref $lrref;
-       return unless defined $lrval;
+       return unless length $lrval;
 
        if (is_fast_fwd $lrval, $currentval) {
            print "OK, you are ahead of $lrref\n" or die $!;
@@ -1128,7 +1130,7 @@ sub do_stitch ($;$) {
     stitch($dangling_head, $ffq_prev, $gdrlast, $ffq_prev_commitish, $prose);
 }
 
-sub cmd_new_upstream_v0 () {
+sub cmd_new_upstream () {
     # automatically and unconditionally launders before rebasing
     # if rebase --abort is used, laundering has still been done
 
@@ -1215,11 +1217,13 @@ sub cmd_new_upstream_v0 () {
           ) {
            my @oldpieces = (split / /, $1);
            my $old_n_parents = scalar @{ $old_upstream->{Parents} };
-           if (@oldpieces != $old_n_parents) {
+           if ($old_n_parents != @oldpieces &&
+               $old_n_parents != @oldpieces + 1) {
                snag 'upstream-confusing', sprintf
                    "previous upstream combine %s".
-                   " mentions %d pieces (each implying one orig commit)".
-                   " but has %d parents",
+                   " mentions %d pieces (each implying one parent)".
+                   " but has %d parents".
+                   " (one per piece plus maybe a previous combine)",
                    $old_upstream->{CommitId},
                    (scalar @oldpieces),
                    $old_n_parents;
@@ -1232,7 +1236,8 @@ sub cmd_new_upstream_v0 () {
                $oldpieces[0] = '';
                foreach my $i (0..$#oldpieces) {
                    my $n = $oldpieces[$i];
-                   $piece->($n, Old => $old_upstream->{CommitId}.'^'.($i+1));
+                   my $hat = 1 + $i + ($old_n_parents - @oldpieces);
+                   $piece->($n, Old => $old_upstream->{CommitId}.'^'.$hat);
                }
            }
        } else {
@@ -1346,6 +1351,8 @@ END
         'launder for new upstream';
 
     my @cmd = (@git, qw(rebase --onto), $new_bw, $old_bw, @ARGV);
+    local $ENV{GIT_REFLOG_ACTION} = git_reflog_action_msg
+       "debrebase new-upstream $new_version: rebase";
     runcmd @cmd;
     # now it's for the user to sort out
 }
@@ -1491,8 +1498,13 @@ sub make_patches_staged ($) {
     in_workarea sub {
        runcmd @git, qw(checkout -q -b bw), $secret_bw;
        runcmd @git, qw(checkout -q -b patch-queue/bw), $secret_head;
-       runcmd qw(gbp pq export);
-       runcmd @git, qw(add debian/patches);
+       my @gbp_cmd = (qw(gbp pq export));
+       my $r = system shell_cmd 'exec >../gbp-pq-err 2>&1', @gbp_cmd;
+       if ($r) {
+           { local ($!,$?); copy('../gbp-pq-err', \*STDERR); }
+           failedcmd @gbp_cmd;
+       }
+       runcmd @git, qw(add -f debian/patches);
     };
 }