summaryrefslogtreecommitdiff
path: root/dgit
diff options
context:
space:
mode:
authorIan Jackson <ijackson@chiark.greenend.org.uk>2016-09-18 23:42:16 +0100
committerIan Jackson <ijackson@chiark.greenend.org.uk>2016-09-25 20:12:52 +0100
commitbd57c194e497ba2c327dde5400e14b573733c21a (patch)
tree3b05f815aeeba75d234c8331ec42abe3f9a3e108 /dgit
parent077ca64d7cfb771c9f4dd278a9b9e2fdb6a4f729 (diff)
Split brain: Make pseudomerge
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Diffstat (limited to 'dgit')
-rwxr-xr-xdgit119
1 files changed, 117 insertions, 2 deletions
diff --git a/dgit b/dgit
index bca6745..39efa04 100755
--- a/dgit
+++ b/dgit
@@ -63,6 +63,7 @@ our $existing_package = 'dpkg';
our $cleanmode;
our $changes_since_version;
our $rmchanges;
+our $overwrite_version;
our $quilt_mode;
our $quilt_modes_re = 'linear|smash|auto|nofix|nocheck|gbp|unapplied';
our $we_are_responder;
@@ -1642,7 +1643,11 @@ sub git_fetch_us () {
# deliberately-not-ff, in which case we must fetch everything.
my @specs = deliberately_not_fast_forward ? qw(tags/*) :
- map { "tags/$_" } debiantags('*',access_basedistro);
+ map { "tags/$_" }
+ (quiltmode_splitbrain
+ ? (map { $_->('*',access_basedistro) }
+ \&debiantag_new, \&debiantag_maintview)
+ : debiantags('*',access_basedistro));
push @specs, server_branch($csuite);
push @specs, qw(heads/*) if deliberately_not_fast_forward;
@@ -2350,6 +2355,114 @@ sub madformat ($) {
return 1;
}
+sub splitbrain_pseudomerge ($$$$) {
+ my ($clogp, $maintview, $dgitview, $archive_hash) = @_;
+ # => $merged_dgitview
+ printdebug "splitbrain_pseudomerge...\n";
+ #
+ # We: debian/PREVIOUS HEAD($maintview)
+ # expect: o ----------------- o
+ # \ \
+ # o o
+ # a/d/PREVIOUS $dgitview
+ # $archive_hash \
+ # If so, \ \
+ # we do: `------------------ o
+ # this: $dgitview'
+ #
+
+ # We work with tuples [ $thing, $what ]
+ # (often $thing is a commit hash; $what is a description)
+
+ my $tag_lookup = sub {
+ my ($tagname, $what) = @_;
+ printdebug "splitbrain_pseudomerge tag_lookup $what\n";
+ my $lrefname = lrfetchrefs."/tags/$tagname";
+ my $tagobj = $lrfetchrefs_f{$lrefname};
+ defined $tagobj or fail <<END;
+Wanted tag $tagname ($what) on dgit server, but not found
+END
+ printdebug "splitbrain_pseudomerge tag_lookup $tagobj $what\n";
+ return [ git_rev_parse($tagobj), $what ];
+ };
+
+ my $cond_equal = sub {
+ my ($x,$y) = @_;
+ $x->[0] eq $y->[0] or fail <<END;
+$x->[1] ($x->[0]) not equal to $y->[1] ($y->[0])
+END
+ };
+ my $cond_ff = sub {
+ my ($anc,$desc) = @_;
+ is_fast_fwd($anc->[0], $desc->[0]) or fail <<END;
+$anc->[1] ($anc->[0]) .. $desc->[1] ($desc->[0]) is not fast forward
+END
+ };
+
+ my $arch_clogp = commit_getclogp $archive_hash;
+ my $i_arch_v = [ (getfield $arch_clogp, 'Version'),
+ 'version currently in archive' ];
+
+ printdebug "splitbrain_pseudomerge i_arch_v @$i_arch_v\n";
+
+ return $dgitview unless defined $archive_hash;
+
+ if ($overwrite_version) {
+ progress "Declaring that HEAD inciudes all changes in archive...";
+ progress "Checking that $overwrite_version does so...";
+ $cond_equal->([ $overwrite_version, '--overwrite= version' ],
+ $i_arch_v);
+ } else {
+ progress "Checking that HEAD inciudes all changes in archive...";
+ }
+
+ return $dgitview if is_fast_fwd $archive_hash, $dgitview;
+
+ my $t_dep14 = debiantag_maintview $i_arch_v->[0], access_basedistro;
+ my $i_dep14 = $tag_lookup->($t_dep14, "maintainer view tag");
+ my $t_dgit = debiantag_new $i_arch_v->[0], access_basedistro;
+ my $i_dgit = $tag_lookup->($t_dgit, "dgit view tag");
+ my $i_archive = [ $archive_hash, "current archive contents" ];
+
+ printdebug "splitbrain_pseudomerge i_archive @$i_archive\n";
+
+ $cond_equal->($i_dgit, $i_archive);
+ $cond_ff->($i_dep14, $i_dgit);
+ $overwrite_version or $cond_ff->($i_dep14, [ $maintview, 'HEAD' ]);
+
+ my $tree = cmdoutput qw(git rev-parse), "${dgitview}:";
+ my $authline = clogp_authline $clogp;
+
+ mkpath '.git/dgit';
+ my $pmf = ".git/dgit/pseudomerge";
+ open MC, ">", $pmf or die "$pmf $!";
+ print MC <<END or die $!;
+tree $tree
+parent $dgitview
+parent $archive_hash
+author $authline
+commiter $authline
+
+END
+ if ($overwrite_version) {
+ print MC <<END;
+Declare fast forward from $overwrite_version
+
+[dgit --quilt=$quilt_mode --overwrite-version=$overwrite_version]
+END
+ } else {
+ print MC <<END;
+Make fast forward from $i_arch_v->[0]
+
+[dgit --quilt=$quilt_mode]
+END
+ }
+ close MC or die $!;
+
+ progress "Making pseudo-merge of $i_arch_v->[0] into dgit view.";
+ return make_commit($pmf);
+}
+
sub push_parse_changelog ($) {
my ($clogpfn) = @_;
@@ -2566,7 +2679,9 @@ END
"--quilt=$quilt_mode but no cached dgit view:
perhaps tree changed since dgit build[-source] ?";
$split_brain = 1;
- $dgithead = $dgitview;
+ $dgithead = splitbrain_pseudomerge($clogp,
+ $actualhead, $dgitview,
+ $archive_hash);
$maintviewhead = $actualhead;
changedir '../../../..';
prep_ud(); # so _only_subdir() works, below