X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=git-debrebase;h=9d87e76760ce866c717e0962fdec78868652bc4f;hb=42a42572cb11e5481d51fecc94daa1ca8f39b2da;hp=2b38d4f85d2cdb89f95b3af03627d09b3516a5e8;hpb=a87e08ae2e6861e87a386dd5c621e3da9c5d41d1;p=dgit.git
diff --git a/git-debrebase b/git-debrebase
index 2b38d4f8..9d87e767 100755
--- a/git-debrebase
+++ b/git-debrebase
@@ -18,66 +18,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-
-# 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
-#
-# git-debrebase [] convert-from-gbp []
-# git-debrebase [] convert-to-gbp
-
-# problems / outstanding questions:
-#
-# * dgit push with a `3.0 (quilt)' package means doing quilt
-# fixup. Usually this involves recommitting the whole patch
-# series, one at a time, with dpkg-source --commit. This is
-# terribly terribly slow. (Maybe this should be fixed in dgit.)
-#
-# * dgit push usually needs to (re)make a pseudomerge. The "first"
-# git-debrebase stripped out the previous pseudomerge and could
-# have remembeed the HEAD. But it's not quite clear what history
-# ought to be preserved and what should be discarded. For now
-# the user will have to tell dgit --overwrite.
-#
-# To fix this, do we need a new push hook for dgit ?
-#
-# * Workflow is currently clumsy. Lots of spurious runes to type.
-# There's not even a guide.
-#
-# * There are no tests.
-#
-# * new-upstream-v0 has a terrible UI. You end up with giant
-# runic command lines.
-#
-# One consequence of the lack of richness it can need --force in
-# fairly sensible situations and there is no way to tell it what
-# you are really trying to do, other than just --force. There
-# should be an interface with some default branch names.
-#
-# * There should be a standard convention for the version number,
-# and unfinalised or not changelog, after new-upstream.
-#
-# * Handing of multi-orig dgit new-upstream .dsc imports is known to
-# be broken. They may be not recognised, improperly converted, or
-# their conversion may be unrecognised.
-#
-# * Docs need writing and updating. Even README.git-debrebase
-# describes a design but may not reflect the implementation.
-#
-# * We need to develop a plausible model that works for derivatives,
-# who probably want to maintain their stack on top of Debian's.
-# downstream-rebase-launder-v0 may be a starting point?
-
use strict;
use Debian::Dgit qw(:DEFAULT :playground);
@@ -91,7 +31,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 +296,8 @@ sub any_fproblems () {
# has additional entry in classification result
# OrigParents = [ subset of Parents ] # singleton list
#
+# TreatAsAnchor
+#
# BreakwaterStart
#
# Unknown
@@ -424,6 +366,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 +378,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 +508,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 +641,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') {
@@ -1074,13 +1038,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 +1066,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 +1370,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 +1380,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 {