}
}
-sub quiltify_trees_differ ($$;$$) {
- my ($x,$y,$finegrained,$ignorenamesr) = @_;
+sub quiltify_trees_differ ($$;$$$) {
+ my ($x,$y,$finegrained,$ignorenamesr,$unrepres) = @_;
# 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
# if $ignorenamesr is defined, $ingorenamesr->{$fn}
# is set for each modified .gitignore filename $fn
+ # if $unrepres is defined, array ref to which is appeneded
+ # a list of unrepresentable changes (removals of upstream files
+ # (as messages)
local $/=undef;
- my @cmd = (@git, qw(diff-tree --name-only -z));
- push @cmd, qw(-r) if $finegrained;
+ my @cmd = (@git, qw(diff-tree -z));
+ push @cmd, qw(--name-only) unless $unrepres;
+ push @cmd, qw(-r) if $finegrained || $unrepres;
push @cmd, $x, $y;
my $diffs= cmdoutput @cmd;
my $r = 0;
+ my @lmodes;
foreach my $f (split /\0/, $diffs) {
+ if ($unrepres && !@lmodes) {
+ @lmodes = $f =~ m/^\:(\w+) (\w+) \w+ \w+ / or die "$_ ?";
+ next;
+ }
+ my ($oldmode,$newmode) = @lmodes;
+ @lmodes = ();
+
next if $f =~ m#^debian(?:/.*)?$#s;
+
+ if ($unrepres) {
+ eval {
+ die "deleted\n" unless $newmode =~ m/[^0]/;
+ die "not a plain file\n" unless $newmode =~ m/^10\d{4}$/;
+ if ($oldmode =~ m/[^0]/) {
+ die "mode changed\n" if $oldmode ne $newmode;
+ } else {
+ die "non-default mode\n" unless $newmode =~ m/^100644$/;
+ }
+ };
+ if ($@) {
+ local $/="\n"; chomp $@;
+ push @$unrepres, [ $f, $@ ];
+ }
+ }
+
my $isignore = $f =~ m#^(?:.*/)?.gitignore$#s;
$r |= $isignore ? 02 : 01;
$ignorenamesr->{$f}=1 if $ignorenamesr && $isignore;
local $ENV{GIT_AUTHOR_DATE} = $authline[2];
if ($quilt_mode =~ m/gbp|unapplied/ &&
- ($diffbits->{H2O} & 01)) {
+ ($diffbits->{O2H} & 01)) {
my $msg =
"--quilt=$quilt_mode specified, implying patches-unapplied git tree\n".
" but git tree differs from orig in upstream files.";
.gitignores: but, such patches exist in debian/patches.
END
}
- if (($diffbits->{H2O} & 02) && # user has modified .gitignore
+ if (($diffbits->{O2H} & 02) && # user has modified .gitignore
!($diffbits->{O2A} & 02)) { # patches do not change .gitignore
quiltify_splitbrain_needed();
progress "dgit view: creating patch to represent .gitignore changes";
ensuredir '.pc';
- runcmd qw(sh -ec),
- 'exec dpkg-source --before-build . >/dev/null';
+ my @bbcmd = (qw(sh -ec), 'exec dpkg-source --before-build . >/dev/null');
+ $!=0; $?=-1;
+ if (system @bbcmd) {
+ failedcmd @bbcmd if $? < 0;
+ fail <<END;
+failed to apply your git tree's patch stack (from debian/patches/) to
+ the corresponding upstream tarball(s). Your source tree and .orig
+ are probably too inconsistent. dgit can only fix up certain kinds of
+ anomaly (depending on the quilt mode). See --quilt= in dgit(1).
+END
+ }
changedir '..';
# be. This is mostly for error reporting.
my %editedignores;
+ my @unrepres;
my $diffbits = {
# H = user's HEAD
# O = orig, without patches applied
# A = "applied", ie orig with H's debian/patches applied
- H2O => quiltify_trees_differ($headref, $unapplied, 1,\%editedignores),
+ O2H => quiltify_trees_differ($unapplied,$headref, 1,
+ \%editedignores, \@unrepres),
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)) {
+ foreach my $v (qw(O2H O2A H2A)) {
push @dl, ($diffbits->{$v} & $b) ? '##' : '==';
}
}
printdebug "differences \@dl @dl.\n";
progress sprintf
+"$us: base trees orig=%.20s o+d/p=%.20s",
+ $unapplied, $oldtiptree;
+ 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];
+ if (@unrepres) {
+ print STDERR "dgit: cannot represent change: $_->[1]: $_->[0]\n"
+ foreach @unrepres;
+ fail <<END;
+HEAD has changes to .orig[s] which are not representable by `3.0 (quilt)'
+END
+ }
+
my @failsuggestion;
- if (!($diffbits->{H2O} & $diffbits->{O2A})) {
+ if (!($diffbits->{O2H} & $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.";