X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=blobdiff_plain;f=git-debrebase;h=aacad91771bdd88746b08b68236522039be276bf;hp=50fa1bc96cfb22e169f9c27406b165047e5b1152;hb=c0781c85a246169edbe7154d2f0073649af82709;hpb=237fe933713ea3d86ed8fbdb86819797b770405b diff --git a/git-debrebase b/git-debrebase index 50fa1bc9..aacad917 100755 --- a/git-debrebase +++ b/git-debrebase @@ -29,6 +29,7 @@ # git-debrebase [ --] [] # git-debrebase [] analyse # git-debrebase [] launder # prints breakwater tip etc. +# git-debrebase [] stitch [--prose=] # git-debrebase [] downstream-rebase-launder-v0 # experimental # # git-debrebase [] gbp2debrebase-v0 \ @@ -100,7 +101,7 @@ sub badusage ($) { sub cfg ($;$) { my ($k, $optional) = @_; - $/ = "\0"; + local $/ = "\0"; my @cmd = qw(git config -z); push @cmd, qw(--get-all) if wantarray; push @cmd, $k; @@ -441,7 +442,7 @@ sub classify ($) { my @overwritten = grep { $_->{Differs} } @p; confess "internal error $objid ?" unless @overwritten==1; return $classify->(qw(Pseudomerge), - Overwritten => $overwritten[0], + Overwritten => [ $overwritten[0] ], Contributor => $identical[0]); } if (@p == 2 && @identical == 2) { @@ -452,7 +453,7 @@ sub classify ($) { } @p; return $classify->(qw(Pseudomerge), SubType => qw(Ambiguous), - Overwritten => $bytime[0], + Overwritten => [ $bytime[0] ], Contributor => $bytime[1]); } foreach my $p (@p) { @@ -626,7 +627,8 @@ sub walk ($;$$) { # suite intended by the non-dgit NMUer, and later # pseudomerges may represent in-archive copies. my $ovwrs = $pm->{Overwritten}; - printf $report " PM=%s \@Overwr:%d", $pm, (scalar @$ovwrs) + printf $report " PM=%s \@Overwr:%d", + $pm->{CommitId}, (scalar @$ovwrs) if $report; if (@$ovwrs != 1) { printdebug "*** WALK BOMB DgitImportUnpatched\n"; @@ -649,26 +651,15 @@ sub walk ($;$$) { %$cl, SpecialMethod => 'DgitImportDebianUpdate', $xmsg->("convert dgit import: debian changes") + }, { + %$cl, + SpecialMethod => 'DgitImportUpstreamUpdate', + $xmsg->("convert dgit import: upstream update", + " breakwater") }; - my $differs = (get_differs $ovwr, $cl->{Tree}); - printf $report " Differs=%#x", $differs if $report; - if ($differs & D_UPS) { - printf $report " D_UPS" if $report; - # This will also trigger if a non-dgit git-based NMU - # deleted .gitignore (which is a thing that some of - # the existing git tools do if the user doesn't - # somehow tell them not to). Ah well. - push @brw_cl, { - %$cl, - SpecialMethod => 'DgitImportUpstreamUpdate', - $xmsg->("convert dgit import: upstream changes", - " breakwater") - }; - } $prline->(" Import"); $rewrite_from_here->(); $upp_limit //= $#upp_cl; # further, deeper, patches discarded - die 'BUG $upp_limit is not used anywhere?'; $cur = $ovwr; next; } else { @@ -710,6 +701,8 @@ sub walk ($;$$) { runcmd @git, qw(read-tree), $treeish; $read_tree_debian->($build); }; + + $#upp_cl = $upp_limit if defined $upp_limit; my $committer_authline = calculate_committer_authline(); @@ -745,8 +738,10 @@ sub walk ($;$$) { next; } elsif ($method eq 'DgitImportDebianUpdate') { $read_tree_debian->($cltree); - rm_subdir_cached qw(debian/patches); } elsif ($method eq 'DgitImportUpstreamUpdate') { + confess unless $rewriting; + my $differs = (get_differs $build, $cltree); + next unless $differs & D_UPS; $read_tree_upstream->($cltree); push @parents, map { $_->{CommitId} } @{ $cl->{OrigParents} }; } else { @@ -832,6 +827,12 @@ sub cmd_launder () { sub defaultcmd_rebase () { my $old = get_head(); + my ($status, $message) = record_ffq_prev(); + if ($status eq 'written' || $status eq 'exists') { + } else { + fproblem $status, "could not record ffq-prev: $message"; + fproblems_maybe_bail(); + } my ($tip,$breakwater) = walk $old; update_head_postlaunder $old, $tip, 'launder for rebase'; runcmd @git, qw(rebase), @ARGV, $breakwater; @@ -850,6 +851,20 @@ sub cmd_analyse () { STDOUT->error and die $!; } +sub ffq_prev_branchinfo () { + # => ('status', "message", [$current, $ffq_prev]) + # 'status' may be + # branch message is undef + # weird-symref } no $current, + # notbranch } no $ffq_prev + my $current = git_get_symref(); + return ('detached', 'detached HEAD') unless defined $current; + return ('weird-symref', 'HEAD symref is not to refs/') + unless $current =~ m{^refs/}; + my $ffq_prev = "refs/$ffq_refprefix/$'"; + return ('branch', undef, $current, $ffq_prev); +} + sub record_ffq_prev () { # => ('status', "message") # 'status' may be @@ -861,11 +876,8 @@ sub record_ffq_prev () { # if not ff from some branch we should be ff from, is an fproblem # if "written", will have printed something about that to stdout, # and also some messages about ff checks - my $current = git_get_symref(); - return ('detached', 'detached HEAD') unless defined $current; - return ('weird-symref', 'HEAD symref is not to refs/') - unless $current =~ m{^refs/}; - my $ffq_prev = "refs/$ffq_refprefix/$'"; + my ($status, $message, $current, $ffq_prev) = ffq_prev_branchinfo(); + return ($status, $message) unless $status eq 'branch'; my $currentval = get_head(); @@ -1119,6 +1131,38 @@ sub cmd_record_ffq_prev () { } } +sub cmd_stitch () { + my $prose = ''; + GetOptions('prose=s', \$prose) or die badusage("bad options to stitch"); + badusage "no arguments allowed" if @ARGV; + my ($status, $message, $current, $ffq_prev) = ffq_prev_branchinfo(); + if ($status ne 'branch') { + fproblem $status, "could not check ffq-prev: $message"; + fproblems_maybe_bail(); + } + my $prev = $ffq_prev && git_get_ref $ffq_prev; + if (!$prev) { + fail "No ffq-prev to stitch." unless $opt_noop_ok; + } + fresh_workarea(); + my $old_head = get_head(); + my $new_head = make_commit [ $old_head, $ffq_prev ], [ + 'Declare fast forward / record previous work', + "[git-debrebase pseudomerge: stitch$prose]", + ]; + my @upd_cmd = (@git, qw(update-ref --stdin)); + debugcmd '>|', @upd_cmd; + open U, "|-", @upd_cmd or die $!; + my $u = <= ", $_, "\n" foreach split /\n/, $u; + print U $u; + printdebug ">\$\n"; + close U or failedcmd @upd_cmd; +} + sub cmd_gbp2debrebase () { badusage "needs 1 optional argument, the upstream" unless @ARGV<=1; my ($upstream_spec) = @ARGV;