chiark / gitweb /
quilt innards: Break out quilt_check_splitbrain_cache (nfc)
[dgit.git] / dgit
diff --git a/dgit b/dgit
index 5207a921adac2e7ad223eab270ffa5ad7129224e..835366eaed8a5efd42878ce52c261f73e56397b9 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -2947,8 +2947,121 @@ sub quilt_fixup_singlepatch ($$$) {
 
     chdir "work";
     commit_quilty_patch();
+}
+
+sub quilt_make_fake_dsc ($) {
+    my ($upstreamversion) = @_;
+
+    my $fakeversion="$upstreamversion-~~DGITFAKE";
+
+    my $fakedsc=new IO::File 'fake.dsc', '>' or die $!;
+    print $fakedsc <<END or die $!;
+Format: 3.0 (quilt)
+Source: $package
+Version: $fakeversion
+Files:
+END
+
+    my $dscaddfile=sub {
+        my ($b) = @_;
+        
+       my $md = new Digest::MD5;
+
+       my $fh = new IO::File $b, '<' or die "$b $!";
+       stat $fh or die $!;
+       my $size = -s _;
+
+       $md->addfile($fh);
+       print $fakedsc " ".$md->hexdigest." $size $b\n" or die $!;
+    };
+
+    quilt_fixup_linkorigs($upstreamversion, $dscaddfile);
+
+    my @files=qw(debian/source/format debian/rules
+                 debian/control debian/changelog);
+    foreach my $maybe (qw(debian/patches debian/source/options
+                          debian/tests/control)) {
+        next unless stat_exists "../../../$maybe";
+        push @files, $maybe;
+    }
+
+    my $debtar= srcfn $fakeversion,'.debian.tar.gz';
+    runcmd qw(env GZIP=-1n tar -zcf), "./$debtar", qw(-C ../../..), @files;
+
+    $dscaddfile->($debtar);
+    close $fakedsc or die $!;
+}
+
+sub quilt_check_splitbrain_cache ($$) {
+    my ($headref, $upstreamversion) = @_;
+    # Checks to see if we are in (potentially) split brain mode.
+    # If so, computes the cache key and looks in the cache.
+    # If split brain is not applicable, returns (undef,0).
+    # Otherwise returns ($cachekey,HIT) where
+    # HIT=0: miss; HIT=1: hit, needs different commit; HIT=2: same commit OK
 
+    quilt_make_fake_dsc($upstreamversion);
+
+    return (undef,0) unless quiltmode_splitbrain();
+
+    my $splitbrain_cachekey;
     
+    progress
+ "dgit: split brain (separate dgit view) may needed (--quilt=$quilt_mode).";
+    # 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, $quilt_mode;
+    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 (<GC>) {
+       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 "dgit view: found cached (commit id $cachehit)";
+           runcmd @git, qw(checkout -q -b dgit-view), $cachehit;
+           $split_brain = 1;
+           return ($splitbrain_cachekey, 1);
+       }
+       progress "dgit view: found cached, no changes required";
+       return ($splitbrain_cachekey, 2);
+    }
+    die $! if GC->error;
+    failedcmd unless close GC;
+
+    printdebug "splitbrain cache miss\n";
+    return ($splitbrain_cachekey, 0);
 }
 
 sub quilt_fixup_multipatch ($$$) {
@@ -3025,103 +3138,10 @@ sub quilt_fixup_multipatch ($$$) {
     # afterwards with dpkg-source --before-build.  That lets us save a
     # tree object corresponding to .origs.
 
-    my $fakeversion="$upstreamversion-~~DGITFAKE";
-
-    my $fakedsc=new IO::File 'fake.dsc', '>' or die $!;
-    print $fakedsc <<END or die $!;
-Format: 3.0 (quilt)
-Source: $package
-Version: $fakeversion
-Files:
-END
-
-    my $dscaddfile=sub {
-        my ($b) = @_;
-        
-       my $md = new Digest::MD5;
-
-       my $fh = new IO::File $b, '<' or die "$b $!";
-       stat $fh or die $!;
-       my $size = -s _;
+    my ($splitbrain_cachekey,$cachehit) =
+       quilt_check_splitbrain_cache($headref, $upstreamversion);
 
-       $md->addfile($fh);
-       print $fakedsc " ".$md->hexdigest." $size $b\n" or die $!;
-    };
-
-    quilt_fixup_linkorigs($upstreamversion, $dscaddfile);
-
-    my @files=qw(debian/source/format debian/rules
-                 debian/control debian/changelog);
-    foreach my $maybe (qw(debian/patches debian/source/options
-                          debian/tests/control)) {
-        next unless stat_exists "../../../$maybe";
-        push @files, $maybe;
-    }
-
-    my $debtar= srcfn $fakeversion,'.debian.tar.gz';
-    runcmd qw(env GZIP=-1n tar -zcf), "./$debtar", qw(-C ../../..), @files;
-
-    $dscaddfile->($debtar);
-    close $fakedsc or die $!;
-
-    my $splitbrain_cachekey;
-    if (quiltmode_splitbrain()) {
-       progress
- "dgit: split brain (separate dgit view) may needed (--quilt=$quilt_mode).";
-       # 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, $quilt_mode;
-       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 (<GC>) {
-           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 "dgit view: found cached (commit id $cachehit)";
-               runcmd @git, qw(checkout -q -b dgit-view), $cachehit;
-               $split_brain = 1;
-               return;
-           }
-           progress "dgit view: found cached, no changes required";
-           return;
-       }
-       die $! if GC->error;
-       failedcmd unless close GC;
-
-       printdebug "splitbrain cache miss\n";
-    }
+    return if $splitbrain_cachekey && $cachehit;
 
     runcmd qw(sh -ec),
         'exec dpkg-source --no-check --skip-patches -x fake.dsc >/dev/null';