X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=git-debrebase;h=f16b9b590de949f1e18a45df360886d6d28470b2;hb=150aff96f5a8740d928e2f677f987bb821b54b4b;hp=71fb11e60f39b7ba7550efe26e63f0db40a34c9e;hpb=de060de5abd543a46a6e08653ccbaef27c556a29;p=dgit.git diff --git a/git-debrebase b/git-debrebase index 71fb11e6..f16b9b59 100755 --- a/git-debrebase +++ b/git-debrebase @@ -110,7 +110,7 @@ use POSIX; use Data::Dumper; use Getopt::Long qw(:config posix_default gnu_compat bundling); -use Debian::Dgit qw(:DEFAULT $wa); +use Debian::Dgit qw(:DEFAULT :playground); sub badusage ($) { my ($m) = @_; @@ -136,15 +136,31 @@ sub get_commit ($) { return ($`,$'); } -sub D_DEB () { return 0x1; } # debian/ (not including debian/patches/) -sub D_UPS () { return 0x2; } # upstream files -sub D_PAT_ADD () { return 0x4; } # debian/patches/ extra patches at end -sub D_PAT_OTH () { return 0x8; } # debian/patches other changes +sub D_UPS () { 0x02; } # upstream files +sub D_PAT_ADD () { 0x04; } # debian/patches/ extra patches at end +sub D_PAT_OTH () { 0x08; } # debian/patches other changes +sub D_DEB_CLOG () { 0x10; } # debian/ (not patches/ or changelog) +sub D_DEB_OTH () { 0x20; } # debian/changelog +sub DS_DEB () { D_DEB_CLOG | D_DEB_OTH; } # debian/ (not patches/) + +our $playprefix = 'debrebase'; +our $rd; +our $workarea; -our $rd = ".git/git-debrebase"; -our $ud = "$rd/work"; our @git = qw(git); +sub in_workarea ($) { + my ($sub) = @_; + changedir $workarea; + my $r = eval { $sub->(); }; + changedir $maindir; +} + +sub fresh_workarea () { + $workarea = fresh_playground "$playprefix/work"; + in_workarea sub { playtree_setup }; +} + sub get_differs ($$) { my ($x,$y) = @_; # This resembles quiltify_trees_differ, in dgit, a bit. @@ -166,16 +182,19 @@ sub get_differs ($$) { }; $rundiff->([qw(--name-only)], [], sub { - $differs |= $_ eq 'debian' ? D_DEB : D_UPS; + $differs |= $_ eq 'debian' ? DS_DEB : D_UPS; }); - if ($differs & D_DEB) { - $differs &= ~D_DEB; + if ($differs & DS_DEB) { + $differs &= ~DS_DEB; $rundiff->([qw(--name-only -r)], [qw(debian)], sub { - $differs |= $_ eq m{^debian/patches/} ? D_PAT_OTH : D_DEB; + $differs |= + m{^debian/patches/} ? D_PAT_OTH : + $_ eq 'debian/changelog' ? D_DEB_CLOG : + D_DEB_OTH; }); die "mysterious debian changes $x..$y" - unless $differs & (D_PAT_OTH|D_DEB); + unless $differs & (D_PAT_OTH|DS_DEB); } if ($differs & D_PAT_OTH) { @@ -315,7 +334,7 @@ sub classify ($) { return $classify->(qw(AddPatches)); } elsif ($d & (D_PAT_ADD|D_PAT_OTH)) { return $unknown->("edits debian/patches"); - } elsif ($d == D_DEB) { + } elsif ($d & DS_DEB and !($d & ~DS_DEB)) { my ($ty,$dummy) = git_cat_file "$ph[0]:debian"; if ($ty eq 'tree') { return $classify->(qw(Packaging)); @@ -326,7 +345,7 @@ sub classify ($) { } } elsif ($d == D_UPS) { return $classify->(qw(Upstream)); - } elsif ($d == (D_DEB|D_UPS)) { + } elsif ($d & DS_DEB and $d & D_UPS and !($d & ~(DS_DEB|D_UPS))) { return $classify->(qw(Mixed)); } elsif ($d == 0) { return $unknown->("no changes"); @@ -381,15 +400,26 @@ sub classify ($) { # 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} & ~DS_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"); } @@ -568,13 +598,13 @@ sub walk ($;$$) { # Now we build it back up again - workarea_fresh(); + fresh_workarea(); my $rewriting = 0; my $rm_tree_cached = sub { my ($subdir) = @_; - runcmd @git, qw(rm --quiet -rf --cached), $subdir; + runcmd @git, qw(rm --quiet -rf --cached --ignore-unmatch), $subdir; }; my $read_tree_debian = sub { my ($treeish) = @_; @@ -688,6 +718,8 @@ enabledebug if $debuglevel; my $toplevel = cmdoutput @git, qw(rev-parse --show-toplevel); chdir $toplevel or die "chdir $toplevel: $!"; +$rd = fresh_playground "$playprefix/misc"; + my $cmd = shift @ARGV; my $cmdfn = $cmd; $cmdfn =~ y/-/_/;