chiark / gitweb /
git-debrebase: merge: Avoid asking user to re-merge debian/
[dgit.git] / git-debrebase
index ef619be4d1141f3cc7aa3d9884538ad9cf34841e..9c444195f66a97d506541cd93db29ad67d5a936a 100755 (executable)
@@ -263,11 +263,15 @@ sub read_tree_debian ($) {
     rm_subdir_cached 'debian/patches';
 }
 
-sub read_tree_upstream ($;$) {
-    my ($treeish, $keep_patches) = @_;
-    my $save = cmdoutput @git, qw(write-tree --prefix=debian/);
+sub read_tree_upstream ($;$$) {
+    my ($treeish, $keep_patches, $tree_with_debian) = @_;
+    # if $tree_with_debian is supplied, will use that for debian/
+    # otherwise will save and restore it.
+    my $debian =
+       $tree_with_debian ? "$tree_with_debian:debian"
+       : cmdoutput @git, qw(write-tree --prefix=debian/);
     runcmd @git, qw(read-tree), $treeish;
-    read_tree_subdir 'debian', $save;
+    read_tree_subdir 'debian', $debian;
     rm_subdir_cached 'debian/patches' unless $keep_patches;
 };
 
@@ -391,8 +395,8 @@ sub merge_series ($$;@) {
        foreach my $q ($base_q, reverse @input_qs) {
            my $s = $q->{MR}{S};
            gbp_pq_export "p-$s", $q->{SeriesBase}, $q->{SeriesTip};
+           my @earlier;
            if (open S, $seriesfile) {
-               my @earlier;
                while (my $patch = <S>) {
                    chomp $patch or die $!;
                    $prereq{$patch} //= {};
@@ -420,6 +424,20 @@ sub merge_series ($$;@) {
                 "[git-debrebase merge-innards patch-queue prep:".
                 " $q->{SeriesTip}]"
             ];
+
+           read_tree_debian $newbase;
+           if (@earlier) {
+               read_tree_subdir 'debian/patches', "$pec:debian/patches";
+           } else {
+               rm_subdir_cached 'debian/patches';
+           }
+           $pec = make_commit [ $pec ], [
+ "Update debian/ (excluding patches) to final to avoid re-merging",
+ "debian/ was already merged and we need to just take that.",
+                "[git-debrebase merge-innards patch-queue packaging:".
+                " $q->{SeriesTip}]"
+            ];
+
            printdebug "pec' $pec\n";
             runcmd @git, qw(reset -q --hard), $pec;
            $q->{MR}{PEC} = $pec;
@@ -518,7 +536,7 @@ sub merge_series ($$;@) {
        foreach my $c (grep /./, split /\n/, cmdoutput @lcmd) {
            my $commit = git_cat_file $c, 'commit';
            printdebug "merge_series series ok, building $c\n";
-           read_tree_upstream $c;
+           read_tree_upstream $c, 0, $newbase;
            my $tree = cmdoutput @git, qw(write-tree);
            $commit =~ s{^parent (\S+)$}{parent $build}m or confess;
            $commit =~ s{^tree (\S+)$}{tree $tree}m      or confess;
@@ -1272,6 +1290,11 @@ sub walk ($;$$$) {
 
     my $rewriting = 0;
 
+    my $read_tree_upstream = sub {
+       my ($treeish) = @_;
+       read_tree_upstream $treeish, 0, $build;
+    };
+
     $#upp_cl = $upp_limit if defined $upp_limit;
  
     my $committer_authline = calculate_committer_authline();
@@ -1299,7 +1322,7 @@ sub walk ($;$$$) {
            if ($method eq 'Debian') {
                read_tree_debian($cltree);
            } elsif ($method eq 'Upstream') {
-               read_tree_upstream($cltree);
+               $read_tree_upstream->($cltree);
            } elsif ($method eq 'StartRewrite') {
                $rewriting = 1;
                next;
@@ -1312,13 +1335,13 @@ sub walk ($;$$$) {
                confess unless $rewriting;
                my $differs = (get_differs $build, $cltree);
                next unless $differs & D_UPS;
-               read_tree_upstream($cltree);
+               $read_tree_upstream->($cltree);
                push @parents, map { $_->{CommitId} } @{ $cl->{OrigParents} };
            } elsif ($method eq 'MergeCreateMergedBreakwaters') {
                print "Found a general merge, will try to tidy it up.\n";
                $rewriting = 1;
-               read_tree_upstream($cl->{MergeBestAnchor});
-               read_tree_upstream($cl->{MergeBestAnchor});
+               $read_tree_upstream->($cl->{MergeBestAnchor});
+               $read_tree_upstream->($cl->{MergeBestAnchor});
                read_tree_debian($cltree);
                @parents = map { $_->{Breakwater} } @{ $cl->{Parents} };
            } elsif ($method eq 'MergeMergeSeries') {
@@ -1328,16 +1351,29 @@ sub walk ($;$$$) {
                    $cl->{MergeInterchangeBaseInfo},
                    @{ $cl->{Parents} };
                $last_anchor = $cl->{MergeBestAnchor};
-               my $check_differs = get_differs $build, $cl->{CommitId};
+
+               # Check for mismerges:
+               my $check = sub {
+                   my ($against, $allow, $what) = @_;
+                   my $differs = get_differs $build, $against;
+                   $nomerge->(sprintf
+       "merge misresolved: %s are not the same (%s %s d.%#x)",
+                              $what, $against, $build, $differs)
+                       if $differs & ~($allow | D_PAT_ADD);
+               };
+
                # Breakwater changes which were in each side of the
-               # merge should be in MergeCreateMergedBreakwaters
-               # output.  Upstream changes are exactly the result
-               # of merge_series.  So the only difference should
-               # be potential laundry results.
-               $nomerge->(sprintf
-                    "merge misresolved: tree is not the same (%s %s d.%#x)",
-                          $cl->{CommitId}, $build, $check_differs)
-                   if $check_differs & ~D_PAT_ADD;
+               # merge will have been incorporated into the
+               # MergeCreateMergedBreakwaters output.  Because the
+               # upstream series was rebased onto the new breakwater,
+               # so should all of the packaging changes which were in
+               # the input.
+               $check->($input, D_UPS, 'debian files');
+
+               # Upstream files are merge_series, which ought to
+               # have been identical to the original merge.
+               $check->($cl->{CommitId}, DS_DEB, 'upstream files');
+
                print "Merge resolution successful.\n";
                next;
            } else {