chiark / gitweb /
Split brain: Actually get gbp pq output back onto dgit-view branch
[dgit.git] / dgit
diff --git a/dgit b/dgit
index 7b9aa52d2e39453924f6d2df84a90554e912e7f2..0812f32ae2e48338a2686ffae70bfcb5050bc580 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -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);
@@ -1316,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;
 }
 
@@ -2512,12 +2515,14 @@ END
     }
 }
 
-sub quiltify_trees_differ ($$;$) {
-    my ($x,$y,$finegrained) = @_;
+sub quiltify_trees_differ ($$;$$) {
+    my ($x,$y,$finegrained,$ignorenamesr) = @_;
     # 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
     local $/=undef;
     my @cmd = (@git, qw(diff-tree --name-only -z));
     push @cmd, qw(-r) if $finegrained;
@@ -2526,7 +2531,9 @@ sub quiltify_trees_differ ($$;$) {
     my $r = 0;
     foreach my $f (split /\0/, $diffs) {
        next if $f =~ m#^debian(?:/.*)?$#s;
-       $r |= ($f =~ m#^(?:.*/)?.gitignore$#s) ? 02 : 01;
+       my $isignore = $f =~ m#^(?:.*/)?.gitignore$#s;
+       $r |= $isignore ? 02 : 01;
+       $ignorenamesr->{$f}=1 if $ignorenamesr && $isignore;
     }
     printdebug "quiltify_trees_differ $x $y => $r\n";
     return $r;
@@ -2549,23 +2556,65 @@ sub quiltify_splitbrain_needed () {
     }
 }
 
-sub quiltify_splitbrain ($) {
-    my ($diffbits) = @_;
+sub quiltify_splitbrain ($$$$$) {
+    my ($clogp, $unapplied, $headref, $diffbits, $editedignores) = @_;
     if ($quilt_mode !~ m/gbp|dpm/) {
        # treat .gitignore just like any other upstream file
        $diffbits = { %$diffbits };
        $_ = !!$_ foreach values %$diffbits;
     }
+    # We would like any commits we generate to be reproducible
+    my @authline = clogp_authline($clogp);
+    local $ENV{GIT_COMMITTER_NAME} =  $authline[0];
+    local $ENV{GIT_COMMITTER_EMAIL} = $authline[1];
+    local $ENV{GIT_COMMITTER_DATE} =  $authline[2];
     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";
+       progress "creating patches-applied version using gbp-pq";
+       open STDOUT, ">/dev/null" or die $!;
+       runcmd shell_cmd 'exec >/dev/null', @gbppq, qw(import);
+       # gbp-pq import creates a fresh branch; push back to dgit-view
+       runcmd @git, qw(update-ref refs/heads/dgit-view HEAD);
+       runcmd @git, qw(checkout dgit-view);
+    }
+    if (($diffbits->{H2O} & 02) && # user has modified .gitignore
+       !($diffbits->{O2A} & 02)) { # patches do not change .gitignore
+       quiltify_splitbrain_needed();
+       progress "creating patch to represent .gitignore changes";
+        ensuredir "debian/patches";
+       my $gipatch = "debian/patches/auto-gitignore";
+       open GIPATCH, ">>", "$gipatch" or die "$gipatch: $!";
+       stat GIPATCH or die "$gipatch: $!";
+       fail "$gipatch already exists; but want to create it".
+           " to record .gitignore changes" if (stat _)[7];
+       print GIPATCH <<END or die "$gipatch: $!";
+Subject: Update .gitignore from Debian packaging branch
+
+The Debian packaging git branch contains these updates to the upstream
+.gitignore file(s).  This patch is autogenerated, to provide these
+updates to users of the official Debian archive view of the package.
+
+[dgit version $our_version]
+---
+END
+        close GIPATCH or die "$gipatch: $!";
+        runcmd shell_cmd "exec >>$gipatch", @git, qw(diff),
+            $unapplied, $headref, "--", sort keys %$editedignores;
+        open SERIES, "+>>", "debian/patches/series" or die $!;
+        defined seek SERIES, -1, 2 or $!==EINVAL or die $!;
+        my $newline;
+        defined read SERIES, $newline, 1 or die $!;
+       print SERIES "\n" or die $! unless $newline eq "\n";
+       print SERIES "auto-gitignore\n" or die $!;
+       close SERIES or die  $!;
+        runcmd @git, qw(add -- debian/patches/series), $gipatch;
+        commit_admin "Commit patch to update .gitignore";
     }
-    die 'xxx gitignore';
+
     die 'xxx memoisation via git-reflog';
-    die 'xxx fast forward';
+    die 'xxx fast forward (should not depend on quilt mode, but will always be needed if we did $split_brain)';
 }
 
 sub quiltify ($$$$) {
@@ -3016,17 +3065,19 @@ END
     rmtree '.pc';
     runcmd @git, qw(add -Af .);
     my $oldtiptree=git_write_tree();
+    printdebug "fake o+d/p tree object $unapplied\n";
     changedir '../work';
 
 
     # We calculate some guesswork now about what kind of tree this might
     # be.  This is mostly for error reporting.
 
+    my %editedignores;
     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),
+        H2O => quiltify_trees_differ($headref,  $unapplied, 1,\%editedignores),
         H2A => quiltify_trees_differ($headref,  $oldtiptree,1),
         O2A => quiltify_trees_differ($unapplied,$oldtiptree,1),
     };
@@ -3055,7 +3106,8 @@ END
         " --quilt=gbp --quilt=dpm --quilt=unapplied ?";
 
     if ($quilt_mode =~ m/gbp|dpm|unapplied/) {
-       quiltify_splitbrain($diffbits);
+       quiltify_splitbrain($clogp, $unapplied, $headref,
+                            $diffbits, \%editedignores);
        return;
     }