X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=blobdiff_plain;f=dgit;h=29cf5076acd0942d746dda59249ef3c7469115c7;hp=295bbdf1ed1c323cb48bdfe9c6cbb3de60fdce32;hb=74cca49dc0958db0556eabfbaf8bdc6d9d639701;hpb=561bf70f8de802ba788e3d2f3be787015e5b02c0 diff --git a/dgit b/dgit index 295bbdf1..29cf5076 100755 --- a/dgit +++ b/dgit @@ -61,7 +61,7 @@ our $cleanmode; our $changes_since_version; our $rmchanges; our $quilt_mode; -our $quilt_modes_re = 'linear|smash|auto|nofix|nocheck'; +our $quilt_modes_re = 'linear|smash|auto|nofix|nocheck|gbp|unapplied'; our $we_are_responder; our $initiator_tempdir; @@ -70,6 +70,8 @@ our %format_ok = map { $_=>1 } ("1.0","3.0 (native)","3.0 (quilt)"); our $suite_re = '[-+.0-9a-z]+'; our $cleanmode_re = 'dpkg-source(?:-d)?|git|git-ff|check|none'; +our $git_authline_re = '^([^<>]+) \<(\S+)\> (\d+ [-+]\d+)$'; + our (@git) = qw(git); our (@dget) = qw(dget); our (@curl) = qw(curl -f); @@ -83,6 +85,7 @@ our (@dpkgbuildpackage) = qw(dpkg-buildpackage -i\.git/ -I.git); our (@dpkgsource) = qw(dpkg-source -i\.git/ -I.git); our (@dpkggenchanges) = qw(dpkg-genchanges); our (@mergechanges) = qw(mergechanges -f); +our (@gbppq) = qw(gbp-pq); our (@changesopts) = (''); our %opts_opt_map = ('dget' => \@dget, # accept for compatibility @@ -114,6 +117,7 @@ autoflush STDOUT 1; our $supplementary_message = ''; our $need_split_build_invocation = 0; +our $split_brain = 0; END { local ($@, $?); @@ -1314,9 +1318,10 @@ sub clogp_authline ($) { $author =~ s#,.*##ms; my $date = cmdoutput qw(date), '+%s %z', qw(-d), getfield($clogp,'Date'); my $authline = "$author $date"; - $authline =~ m/^[^<>]+ \<\S+\> \d+ [-+]\d+$/ or + $authline =~ m/$git_authline_re/o or fail "unexpected commit author line format \`$authline'". " (was generated from changelog Maintainer field)"; + return ($1,$2,$3) if wantarray; return $authline; } @@ -2511,17 +2516,23 @@ END } sub quiltify_trees_differ ($$;$) { - my ($x,$y,$ignoregitignore) = @_; - # returns 1 iff the two tree objects differ other than in debian/ + my ($x,$y,$finegrained) = @_; + # returns true iff the two tree objects differ other than in debian/ + # with $finegrained, + # returns bitmask 01 - differ in upstream files except .gitignore + # 02 - differ in .gitignore local $/=undef; - my @cmd = (@git, qw(diff-tree --name-only -z), $x, $y); + my @cmd = (@git, qw(diff-tree --name-only -z)); + push @cmd, qw(-r) if $finegrained; + push @cmd, $x, $y; my $diffs= cmdoutput @cmd; + my $r = 0; foreach my $f (split /\0/, $diffs) { - next if $f eq 'debian'; - next if $f eq '.gitignore' && $ignoregitignore; - return 1; + next if $f =~ m#^debian(?:/.*)?$#s; + $r |= ($f =~ m#^(?:.*/)?.gitignore$#s) ? 02 : 01; } - return 0; + printdebug "quiltify_trees_differ $x $y => $r\n"; + return $r; } sub quiltify_tree_sentinelfiles ($) { @@ -2531,17 +2542,37 @@ sub quiltify_tree_sentinelfiles ($) { qw(-- debian/rules debian/control); $r =~ s/\n/,/g; return $r; + } + +sub quiltify_splitbrain_needed () { + if (!$split_brain) { + progress "creating dgit view"; + runcmd @git, qw(checkout -q -b dgit-view); + $split_brain = 1; + } } -sub quilt_could_gbp ($$$) { - my ($userhead,$unapplied,$applied) = @_; - return - !quiltify_trees_differ($userhead,$unapplied,1) && - quiltify_trees_differ($userhead,$applied,1); +sub quiltify_splitbrain ($$) { + my ($clogp, $diffbits) = @_; + if ($quilt_mode !~ m/gbp|dpm/) { + # treat .gitignore just like any other upstream file + $diffbits = { %$diffbits }; + $_ = !!$_ foreach values %$diffbits; + } + if ($quilt_mode =~ m/gbp|unapplied/ && + ($diffbits->{O2A} & 01) && # some patches + !($diffbits->{H2O} & 01)) { # but HEAD is like orig + quiltify_splitbrain_needed(); + runcmd @gbppq, qw(import); + die "SPLIT BRAIN"; + } + die 'xxx gitignore'; + die 'xxx memoisation via git-reflog'; + die 'xxx fast forward'; } sub quiltify ($$$$) { - my ($clogp,$target,$unapplied,$oldtiptree) = @_; + my ($clogp,$target,$oldtiptree,$failsuggestion) = @_; # Quilt patchification algorithm # @@ -2679,12 +2710,7 @@ sub quiltify ($$$$) { foreach my $notp (@nots) { print STDERR "$us: ", $reportnot->($notp), "\n"; } - if (quilt_could_gbp($target,$unapplied,$oldtiptree)) { - print STDERR < quiltify_trees_differ($headref, $unapplied, 1), + H2A => quiltify_trees_differ($headref, $oldtiptree,1), + O2A => quiltify_trees_differ($unapplied,$oldtiptree,1), + }; + + my @dl; + foreach my $b (qw(01 02)) { + foreach my $v (qw(H2O O2A H2A)) { + push @dl, ($diffbits->{$v} & $b) ? '##' : '=='; + } + } + printdebug "differences \@dl @dl.\n"; + + progress sprintf +"$us: quilt differences: src: %s orig %s gitignores: %s orig %s\n". +"$us: quilt differences: HEAD %s o+d/p HEAD %s o+d/p", + $dl[0], $dl[1], $dl[3], $dl[4], + $dl[2], $dl[5]; + + my @failsuggestion; + if (!($diffbits->{H2O} & $diffbits->{O2A})) { + push @failsuggestion, "This might be a patches-unapplied branch."; + } elsif (!($diffbits->{H2A} & $diffbits->{O2A})) { + push @failsuggestion, "This might be a patches-applied branch."; + } + push @failsuggestion, "Maybe you need to specify one of". + " --quilt=gbp --quilt=dpm --quilt=unapplied ?"; + + if ($quilt_mode =~ m/gbp|dpm|unapplied/) { + quiltify_splitbrain($clogp, $diffbits); + return; + } + + quiltify($clogp,$headref,$oldtiptree,\@failsuggestion); if (!open P, '>>', ".pc/applied-patches") { $!==&ENOENT or die $!;