diff options
author | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2016-10-24 01:06:29 +0100 |
---|---|---|
committer | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2016-10-24 01:43:50 +0100 |
commit | 05db7ab051736bb106467e7f83b9e45684dd227c (patch) | |
tree | 6966a7c098c3eb6e3b9d54ca37094b36b4cbd01e /dgit | |
parent | 5c10d34a99f5c4c1eac28aca58d5d7e414fd91f2 (diff) |
Import: Use absurd `git apply' emulation if gbp pq import fails
gbp import can fail due to git apply not understanding patches.
This is #841867 (against dgit).
The underlying problem is #841866 (in gbp pq) which exposes things
like #841865 and #829067 (in git). I imagine there are other lurking
incompatibilities between git-apply and dpkg-source.
We could in principle reimplement the gbp patch metadata extraction.
But that would be quite tiresome and have its own compatibility
problems.
The real problem is just `git apply'. (Indeed gbp already tries git
apply without, and then with, a whitespace fix option.) We work
around the trouble by providing our own implementation of `git apply'.
Specifically:
We try to do things the sane way (just running gbp pq import) first.
If that works, great. If it doesn't, we put /usr/share/dgit/absurd on
the PATH. That contains only a sh script called `git'. This sh
script figures out whether the caller is trying to invoke `git apply'.
If not, it runs the real git.
If the caller wanted git-apply, the absurd git script emulates it
using dpkg-source --before-build. Conveniently, we know that the
series file will not be touched by patches. So we can write just the
patch we care about into the series file, and run --before-build,
which applies just that one patch.
The results are committed (minus the .pc), and for the next patch,
dpkg-source sees again a tree with simply a single patch to apply.
We try ordinary gbp pq first because our absurd approach is very slow
on a big tree. Also we would like to maximise our chances of the
import working. If git and/or gbp ever work better by themselves, all
of this craziness will simply not happen.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Diffstat (limited to 'dgit')
-rwxr-xr-x | dgit | 49 |
1 files changed, 36 insertions, 13 deletions
@@ -1954,25 +1954,48 @@ END local $ENV{GIT_AUTHOR_EMAIL} = $authline[1]; local $ENV{GIT_AUTHOR_DATE} = $authline[2]; - eval { - runcmd shell_cmd 'exec >/dev/null 2>../../gbp-pq-output', - gbp_pq, qw(import); - }; - if ($@) { - { local $@; eval { runcmd qw(cat ../../gbp-pq-output); }; } - die $@; - } + my $path = $ENV{PATH} or die; + + foreach my $use_absurd (qw(0 1)) { + local $ENV{PATH} = $path; + if ($use_absurd) { + chomp $@; + progress "warning: $@"; + $path = "$absurdity:$path"; + progress "$us: trying slow absurd-git-apply..."; + rename "../../gbp-pq-output","../../gbp-pq-output.0" + or die $!; + } + eval { + local $ENV{PATH} = $path if $use_absurd; + + my @showcmd = (gbp_pq, qw(import)); + my @realcmd = shell_cmd + 'exec >/dev/null 2>../../gbp-pq-output', @showcmd; + debugcmd "+",@realcmd; + if (system @realcmd) { + die +(shellquote @showcmd). + " failed: ". + failedcmd_waitstatus()."\n"; + } - my $gapplied = git_rev_parse('HEAD'); - my $gappliedtree = cmdoutput @git, qw(rev-parse HEAD:); - $gappliedtree eq $dappliedtree or - fail <<END; + my $gapplied = git_rev_parse('HEAD'); + my $gappliedtree = cmdoutput @git, qw(rev-parse HEAD:); + $gappliedtree eq $dappliedtree or + fail <<END; gbp-pq import and dpkg-source disagree! gbp-pq import gave commit $gapplied gbp-pq import gave tree $gappliedtree dpkg-source --before-build gave tree $dappliedtree END - $rawimport_hash = $gapplied; + $rawimport_hash = $gapplied; + }; + last unless $@; + } + if ($@) { + { local $@; eval { runcmd qw(cat ../../gbp-pq-output); }; } + die $@; + } } progress "synthesised git commit from .dsc $cversion"; |