X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=blobdiff_plain;f=dgit;h=39efa04a2189491f45441039c45f2320c1a22ad4;hp=e125922ec11ad91cd4590ac6ffbb44faa902fa5d;hb=15b1af481906f016401f5c16fc548538ad43e806;hpb=4ce800ddb6a9f36b35e2a468af7d20e9604d2601 diff --git a/dgit b/dgit index e125922e..39efa04a 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; @@ -2127,10 +2132,7 @@ END if (defined $skew_warning_vsn) { mkpath '.git/dgit'; printdebug "SKEW CHECK WANT $skew_warning_vsn\n"; - my $clogf = ".git/dgit/changelog.tmp"; - runcmd shell_cmd "exec >$clogf", - @git, qw(cat-file blob), "$hash:debian/changelog"; - my $gotclogp = parsechangelog("-l$clogf"); + my $gotclogp = commit_getclogp($hash); my $got_vsn = getfield $gotclogp, 'Version'; printdebug "SKEW CHECK GOT $got_vsn\n"; if (version_compare($got_vsn, $skew_warning_vsn) < 0) { @@ -2353,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 <[0] eq $y->[0] or fail <[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 <[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 <[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) = @_; @@ -2400,6 +2510,7 @@ sub push_tagwants ($$$$) { $tw->{Tag} = $tw->{TagFn}($cversion, access_basedistro); $tw->{Tfn} = sub { $tfbase.$tw->{TfSuffix}.$_[0]; }; } + printdebug 'push_tagwants: ', Dumper(\@_, \@tagwants); return @tagwants; } @@ -2568,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 @@ -2693,11 +2806,6 @@ END my @pushrefs = $forceflag.$dgithead.":".rrref(); foreach my $tw (@tagwants) { - my $view = $tw->{View}; - next unless $view eq 'dgit' - or any { $_ eq $view } access_cfg_tagformats(); - # ^ $view is "dgit" or "maint" so this looks for "maint" - # in archive supported tagformats. push @pushrefs, $forceflag."refs/tags/$tw->{Tag}"; }