X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=git-debrebase;h=41373f3e82f4083291bb74f586ba229303b799ef;hb=e2ef34589c5758d96f492bec534eb9b3398fa960;hp=18bc21f0dbb965b48f4aebc4c8a07d7e67e4ba3e;hpb=52d1506110771ee16b19be4c6b82e06559c9e6f5;p=dgit.git diff --git a/git-debrebase b/git-debrebase index 18bc21f0..41373f3e 100755 --- a/git-debrebase +++ b/git-debrebase @@ -55,7 +55,8 @@ our ($opt_defaultcmd_interactive); our $us = qw(git-debrebase); -our $wrecknoteprefix = 'refs/debrebase-wreckage'; +our $wrecknoteprefix = 'refs/debrebase/wreckage'; +our $merge_cache_ref = 'refs/debrebase/merge-resolutions'; $|=1; @@ -372,9 +373,6 @@ sub gbp_pq_export ($$$) { # xxx general gdr docs highlight forbidden things # xxx general gdr docs list allowable things ? # xxx general gdr docs explicitly forbid some rebase -# -# xxx provide a way for the user to help -# xxx (eg, provide wreckage provide way to continue) # later/rework? # use git-format-patch? @@ -428,6 +426,8 @@ sub merge_attempt_cmd { } } +sub merge_series_patchqueue_convert ($$$); + sub merge_series ($$$;@) { my ($newbase, $wrecknotes, $base_q, @input_qs) = @_; # $base_q{SeriesBase} $input_qs[]{SeriesBase} @@ -452,7 +452,6 @@ sub merge_series ($$$;@) { # $prereq{}{} exists or not (even later) - my $result; my $merged_pq; my $mwrecknote = sub { &mwrecknote($wrecknotes, @_); }; @@ -595,7 +594,17 @@ sub merge_series ($$$;@) { runcmd @git, qw(commit --quiet -m), 'Merged patch queue form'; $merged_pq = git_rev_parse 'HEAD'; $mwrecknote->('merged-patchqueue', $merged_pq); + }; + return merge_series_patchqueue_convert + $wrecknotes, $newbase, $merged_pq; +} + +sub merge_series_patchqueue_convert ($$$) { + my ($wrecknotes, $newbase, $merged_pq) = @_; + my $result; + in_workarea sub { + playtree_setup(); printdebug "merge_series series gbp pq import\n"; runcmd @git, qw(checkout -q -b mergec), $merged_pq; @@ -1469,11 +1478,20 @@ sub walk ($;$$$) { read_tree_debian($cltree); @parents = map { $_->{Breakwater} } @{ $cl->{Parents} }; } elsif ($method eq 'MergeMergeSeries') { - print "Running merge resolution for $cl->{CommitId}...\n"; - $build = merge_series - $build, $cl->{MergeWreckNotes}, - $cl->{MergeInterchangeBaseInfo}, - @{ $cl->{Parents} }; + my $cachehit = reflog_cache_lookup + $merge_cache_ref, "vanilla-merge $cl->{CommitId}"; + if ($cachehit) { + print "Using supplied resolution for $cl->{CommitId}...\n"; + $build = $cachehit; + $mwrecknote->('cached-resolution', $build); + } else { + print "Running merge resolution for $cl->{CommitId}...\n"; + $mwrecknote->('new-base', $build); + $build = merge_series + $build, $cl->{MergeWreckNotes}, + $cl->{MergeInterchangeBaseInfo}, + @{ $cl->{Parents} }; + } $last_anchor = $cl->{MergeBestAnchor}; # Check for mismerges: @@ -2192,19 +2210,32 @@ sub cmd_conclude () { sub cmd_scrap () { if (currently_rebasing()) { runcmd @git, qw(rebase --abort); + push @deferred_updates, 'verify HEAD HEAD'; + # noop, but stops us complaining that scrap was a noop } + badusage "no arguments allowed" if @ARGV; my ($ffq_prev, $gdrlast, $ffq_prev_commitish) = ffq_prev_info(); - if (!$ffq_prev_commitish) { + my $scrapping_head; + if ($ffq_prev_commitish) { + $scrapping_head = get_head(); + push @deferred_updates, + "update $gdrlast $ffq_prev_commitish $git_null_obj", + "update $ffq_prev $git_null_obj $ffq_prev_commitish"; + } + if (git_get_ref $merge_cache_ref) { + push @deferred_updates, + "delete $merge_cache_ref"; + } + if (!@deferred_updates) { fail "No ongoing git-debrebase session." unless $opt_noop_ok; finish 0; } - my $scrapping_head = get_head(); - badusage "no arguments allowed" if @ARGV; - push @deferred_updates, - "update $gdrlast $ffq_prev_commitish $git_null_obj", - "update $ffq_prev $git_null_obj $ffq_prev_commitish"; snags_maybe_bail(); - update_head_checkout $scrapping_head, $ffq_prev_commitish, "scrap"; + if ($scrapping_head) { + update_head_checkout $scrapping_head, $ffq_prev_commitish, "scrap"; + } else { + run_deferred_updates "scrap"; + } } sub make_patches_staged ($) { @@ -2599,6 +2630,46 @@ END 'convert-from-dgit-view'; } +sub cmd_record_resolved_merge () { + badusage "record-resolved-merge takes no further arguments" if @ARGV; + # xxx needs documentation + my $new = get_head(); + my $method; + + print "Checking how you have resolved the merge problem\n"; + my $nope = sub { print "Not $method: @_"; 0; }; + + my $maybe = sub { print "Seems to be $method.\n"; }; + my $yes = sub { + my ($key, $ref) = @_; + reflog_cache_insert $merge_cache_ref, $key, $ref; + print "OK. You can switch branches and try git-debrebase again.\n"; + 1; + }; + + fresh_workarea 'merge'; + sub { + $method = 'vanilla-merge patchqueue'; + my $vanilla = git_get_ref "$wrecknoteprefix/vanilla-merge"; + $vanilla or return $nope->("wreckage was not of vanilla-merge"); + foreach my $lr (qw(left right)) { + my $n = "$wrecknoteprefix/$lr-patchqueue"; + my $lrpq = git_get_ref $n; + $lrpq or return $nope->("wreckage did not contain patchqueues"); + is_fast_fwd $lrpq, $new or return $nope->("HEAD not ff of $n"); + } + $maybe->(); + my $newbase = git_get_ref "$wrecknoteprefix/new-base" + or die "wreckage element $wrecknoteprefix/new-base missing"; + my $result = merge_series_patchqueue_convert + {}, $newbase, $new; + $yes->("vanilla-merge $vanilla", $result); + 1; + }->() or sub { + fail "No resolved merge method seems applicable.\n"; + }->(); +} + sub cmd_downstream_rebase_launder_v0 () { badusage "needs 1 argument, the baseline" unless @ARGV==1; my ($base) = @ARGV;