chiark / gitweb /
git-debrebase: classify: tolerate backwards breakwater merges
[dgit.git] / git-debrebase
index c999dd62c89390f5ffdee37b2d502245515ab6bd..8f2e922355e440f7227a1f7afa3fd8bd8aa61753 100755 (executable)
@@ -144,21 +144,19 @@ sub D_PAT_OTH () { return 0x8; } # debian/patches other changes
 
 our $playprefix = 'debrebase';
 our $rd;
+our $workarea;
 
 our @git = qw(git);
 
 sub in_workarea ($) {
     my ($sub) = @_;
-    changedir "$playground/work";
+    changedir $workarea;
     my $r = eval { $sub->(); };
     changedir $maindir;
 }
 
 sub fresh_workarea () {
-    do {
-       local $playground;
-       fresh_playground "$playprefix/work";
-    };
+    $workarea = fresh_playground "$playprefix/work";
     in_workarea sub { playtree_setup };
 }
 
@@ -392,23 +390,32 @@ sub classify ($) {
     my ($stype, $series) = git_cat_file "$t:debian/patches/series";
     my $haspatches = $stype ne 'missing' && $series =~ m/^\s*[^#\n\t ]/m;
 
-@p = reverse @p; #xxx
-
     # How to decide about l/r ordering of breakwater merges ?  git
     # --topo-order prefers to expand 2nd parent first.  There's
     # already an easy rune to look for debian/ history anyway (git log
     # debian/) so debian breakwater branch should be 1st parent; that
     # way also there's also an easy rune to look for the upstream
     # patches (--topo-order).
-    if (@p == 2 &&
-       !$haspatches &&
-       !$p[0]{IsOrigin} && # breakwater merge never starts with an origin
-       !($p[0]{Differs} & ~D_DEB) &&
-       !($p[1]{Differs} & ~D_UPS)) {
-       return $classify->(qw(BreakwaterUpstreamMerge),
-                          OrigParents => [ $p[1] ]);
+
+    # The above tells us which way *we* will generate them.  But we
+    # might encounter ad-hoc breakwater merges generated manually,
+    # which might be the other way around.  In principle, in some odd
+    # situations, a breakwater merge might have two identical parents.
+    # In that case we guess which way round it is (ie, which parent
+    # has the upstream history).  The order of the 2-iteration loop
+    # controls which guess we make.
+
+    foreach my $prevbrw (qw(0 1)) {
+       if (@p == 2 &&
+           !$haspatches &&
+           !$p[$prevbrw]{IsOrigin} && # breakwater never starts with an origin
+           !($p[$prevbrw]{Differs} & ~D_DEB) &&
+           !($p[!$prevbrw]{Differs} & ~D_UPS)) {
+           return $classify->(qw(BreakwaterUpstreamMerge),
+                              OrigParents => [ $p[!$prevbrw] ]);
+       }
+       # xxx multi-.orig upstreams
     }
-    # xxx multi-.orig upstreams
 
     return $unknown->("complex merge");
 }
@@ -707,8 +714,7 @@ enabledebug if $debuglevel;
 my $toplevel = cmdoutput @git, qw(rev-parse --show-toplevel);
 chdir $toplevel or die "chdir $toplevel: $!";
 
-fresh_playground $playprefix;
-$rd = ensure_a_playground "playprefix/misc";
+$rd = fresh_playground "$playprefix/misc";
 
 my $cmd = shift @ARGV;
 my $cmdfn = $cmd;