From 35786bae6f659ab4c0595c829e2b436e0c292d1c Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 4 Jun 2016 17:10:17 +0100 Subject: [PATCH] Split brain: Memoise (cache) split brain dgit-view in a reflog --- dgit | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/dgit b/dgit index 0812f32a..b22d6ab3 100755 --- a/dgit +++ b/dgit @@ -71,6 +71,7 @@ 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 $splitbraincache = 'dgit-intern/quilt-cache'; our (@git) = qw(git); our (@dget) = qw(dget); @@ -2556,8 +2557,9 @@ sub quiltify_splitbrain_needed () { } } -sub quiltify_splitbrain ($$$$$) { - my ($clogp, $unapplied, $headref, $diffbits, $editedignores) = @_; +sub quiltify_splitbrain ($$$$$$) { + my ($clogp, $unapplied, $headref, $diffbits, + $editedignores, $cachekey) = @_; if ($quilt_mode !~ m/gbp|dpm/) { # treat .gitignore just like any other upstream file $diffbits = { %$diffbits }; @@ -2613,8 +2615,17 @@ END commit_admin "Commit patch to update .gitignore"; } - die 'xxx memoisation via git-reflog'; + my $dgitview = git_rev_parse 'refs/heads/dgit-view'; + + changedir '../../../..'; + ensuredir ".git/logs/refs/dgit-intern"; + my $makelogfh = new IO::File ".git/logs/refs/$splitbraincache", '>>' + or die $!; + runcmd @git, qw(update-ref -m), $cachekey, "refs/$splitbraincache", + $dgitview; + die 'xxx fast forward (should not depend on quilt mode, but will always be needed if we did $split_brain)'; + changedir '.git/dgit/unpack/work'; } sub quiltify ($$$$) { @@ -3026,6 +3037,63 @@ END $dscaddfile->($debtar); close $fakedsc or die $!; + my $splitbrain_cachekey; + if ($quilt_mode =~ m/gbp|dpm|unapplied/) { + # we look in the reflog of dgit-intern/quilt-cache + # we look for an entry whose message is the key for the cache lookup + my @cachekey = (qw(dgit), $our_version); + push @cachekey, $upstreamversion; + push @cachekey, $headref; + + push @cachekey, hashfile('fake.dsc'); + + my $srcshash = Digest::SHA->new(256); + my %sfs = ( %INC, '$0(dgit)' => $0 ); + foreach my $sfk (sort keys %sfs) { + $srcshash->add($sfk," "); + $srcshash->add(hashfile($sfs{$sfk})); + $srcshash->add("\n"); + } + push @cachekey, $srcshash->hexdigest(); + $splitbrain_cachekey = "@cachekey"; + + my @cmd = (@git, qw(reflog), '--pretty=format:%H %gs', + $splitbraincache); + printdebug "splitbrain cachekey $splitbrain_cachekey\n"; + debugcmd "|(probably)",@cmd; + my $child = open GC, "-|"; defined $child or die $!; + if (!$child) { + chdir '../../..' or die $!; + if (!stat ".git/logs/refs/$splitbraincache") { + $! == ENOENT or die $!; + printdebug ">(no reflog)\n"; + exit 0; + } + exec @cmd; die $!; + } + while () { + chomp; + printdebug ">| ", $_, "\n" if $debuglevel > 1; + next unless m/^(\w+) (\S.*\S)$/ && $2 eq $splitbrain_cachekey; + + my $cachehit = $1; + quilt_fixup_mkwork($headref); + if ($cachehit ne $headref) { + progress "quilt fixup ($quilt_mode mode) found cached tree"; + runcmd @git, qw(checkout -q -b dgit-view), $cachehit; + $split_brain = 1; + return; + } + progress "quilt fixup ($quilt_mode mode)". + " found cached indication that no changes needed"; + return; + } + die $! if GC->error; + failedcmd unless close GC; + + printdebug "splitbrain cache miss\n"; + } + runcmd qw(sh -ec), 'exec dpkg-source --no-check --skip-patches -x fake.dsc >/dev/null'; @@ -3105,9 +3173,10 @@ END push @failsuggestion, "Maybe you need to specify one of". " --quilt=gbp --quilt=dpm --quilt=unapplied ?"; - if ($quilt_mode =~ m/gbp|dpm|unapplied/) { + if ($splitbrain_cachekey) { quiltify_splitbrain($clogp, $unapplied, $headref, - $diffbits, \%editedignores); + $diffbits, \%editedignores, + $splitbrain_cachekey); return; } -- 2.30.2