X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=git-debrebase;h=2520d52c5555f501eabd241b73393874c7d68294;hb=75d0b8d7275c035f76db79e7cf7e802e061a9bee;hp=8e472514c34f82c92affe9dd629a71a7c770a28e;hpb=e68aa7468e1c7bb526e74bc90255744ef69b0338;p=dgit.git diff --git a/git-debrebase b/git-debrebase index 8e472514..2520d52c 100755 --- a/git-debrebase +++ b/git-debrebase @@ -21,15 +21,7 @@ # usages: # -# git-debrebase [] new-upstream-v0 \ -# \ -# [ ...] \ -# [...] -# -# git-debrebase [ --] [] # git-debrebase [] analyse -# git-debrebase [] breakwater # prints breakwater tip only -# git-debrebase [] stitch [--prose=] # git-debrebase [] launder-v0 # prints breakwater tip etc. # git-debrebase [] downstream-rebase-launder-v0 # experimental # @@ -91,7 +83,7 @@ use Getopt::Long qw(:config posix_default gnu_compat bundling); use Dpkg::Version; use File::FnMatch qw(:fnmatch); -our ($opt_force, $opt_noop_ok); +our ($opt_force, $opt_noop_ok, @opt_anchors); our $us = qw(git-debrebase); @@ -356,6 +348,8 @@ sub any_fproblems () { # has additional entry in classification result # OrigParents = [ subset of Parents ] # singleton list # +# TreatAsAnchor +# # BreakwaterStart # # Unknown @@ -424,6 +418,10 @@ sub classify ($) { return $r; }; + if (grep { $_ eq $objid } @opt_anchors) { + return $classify->('TreatAsAnchor'); + } + my @identical = grep { !$_->{Differs} } @p; my ($stype, $series) = git_cat_file "$t:debian/patches/series"; my $haspatches = $stype ne 'missing' && $series =~ m/^\s*[^#\n\t ]/m; @@ -432,6 +430,23 @@ sub classify ($) { # multi-orig upstreams are represented with an anchor merge # from a single upstream commit which combines the orig tarballs + # Every anchor tagged this way must be a merge. + # We are relying on the + # [git-debrebase anchor: ...] + # commit message annotation in "declare" anchor merges (which + # do not have any upstream changes), to distinguish those + # anchor merges from ordinary pseudomerges (which we might + # just try to strip). + # + # However, the user is going to be doing git-rebase a lot. We + # really don't want them to rewrite an anchor commit. + # git-rebase trips up on merges, so that is a useful safety + # catch. + # + # BreakwaterStart commits are also anchors in the terminology + # of git-debrebase(5), but they are untagged (and always + # manually generated). + my $badanchor = sub { $unknown->("git-debrebase \`anchor' but @_"); }; @p == 2 or return $badanchor->("has other than two parents"); $haspatches and return $badanchor->("contains debian/patches"); @@ -545,6 +560,7 @@ sub breakwater_of ($) { $ty eq 'Changelog') { $breakwater //= $head; } elsif ($ty eq 'Anchor' or + $ty eq 'TreatAsAnchor' or $ty eq 'BreakwaterStart') { $breakwater //= $head; last; @@ -677,7 +693,7 @@ sub walk ($;$$) { $rewrite_from_here->(\@upp_cl); $cur = $contrib; next; - } elsif ($ty eq 'Anchor') { + } elsif ($ty eq 'Anchor' or $ty eq 'TreatAsAnchor') { $last_anchor = $cur; $build_start->("Anchor", $cur); } elsif ($ty eq 'DgitImportUnpatched') { @@ -1025,13 +1041,13 @@ sub cmd_new_upstream_v0 () { my %pieces; - badusage "need NEW-VERSION UPS-COMMITTISH" unless @ARGV >= 2; + badusage "need NEW-VERSION [UPS-COMMITTISH]" unless @ARGV >= 1; # parse args - low commitment my $new_version = (new Dpkg::Version scalar(shift @ARGV), check => 1); my $new_upstream_version = $new_version->version(); - my $new_upstream = git_rev_parse shift @ARGV; + my $new_upstream = git_rev_parse (shift @ARGV // 'upstream'); record_ffq_auto(); @@ -1074,13 +1090,17 @@ sub cmd_new_upstream_v0 () { my $old_bw_cl = classify $old_bw; my $old_anchor_cl = classify $old_anchor; - confess unless $old_anchor_cl->{OrigParents}; - my $old_upstream = parsecommit - $old_anchor_cl->{OrigParents}[0]{CommitId}; - - $piece->('', Old => $old_upstream->{CommitId}); + my $old_upstream; + if (!$old_anchor_cl->{OrigParents}) { + fproblem 'anchor-treated', + 'old anchor is recognised due to --anchor, cannot check upstream'; + } else { + $old_upstream = parsecommit + $old_anchor_cl->{OrigParents}[0]{CommitId}; + $piece->('', Old => $old_upstream->{CommitId}); + } - if ($old_upstream->{Msg} =~ m{^\[git-debrebase }m) { + if ($old_upstream && $old_upstream->{Msg} =~ m{^\[git-debrebase }m) { if ($old_upstream->{Msg} =~ m{^\[git-debrebase upstream-combine \.((?: $extra_orig_namepart_re)+)\:.*\]$}m ) { @@ -1098,7 +1118,9 @@ sub cmd_new_upstream_v0 () { } foreach my $pc (values %pieces) { - if (!$pc->{Old}) { + if (!$old_upstream) { + # we have complained already + } elsif (!$pc->{Old}) { fproblem 'upstream-new-piece', "introducing upstream piece \`$pc->{Name}'"; } elsif (!$pc->{New}) { @@ -1400,6 +1422,7 @@ sub cmd_downstream_rebase_launder_v0 () { GetOptions("D+" => \$debuglevel, 'noop-ok', => \$opt_noop_ok, 'f=s' => \@fproblem_force_opts, + 'anchor=s' => \@opt_anchors, 'force!') or die badusage "bad options\n"; initdebug('git-debrebase '); enabledebug if $debuglevel; @@ -1409,6 +1432,8 @@ chdir $toplevel or die "chdir $toplevel: $!"; $rd = fresh_playground "$playprefix/misc"; +@opt_anchors = map { git_rev_parse $_ } @opt_anchors; + if (!@ARGV || $ARGV[0] =~ m{^-}) { defaultcmd_rebase(); } else {