chiark / gitweb /
git-debrebase: comment: explain why tagged linear anchors are evil
[dgit.git] / git-debrebase
index 599fe150d12cdbae0038183976cc1f4f594b1b62..524631787575bb459556a696c92850e040a8b970 100755 (executable)
@@ -32,12 +32,14 @@ use Dpkg::Version;
 use File::FnMatch qw(:fnmatch);
 
 our ($opt_force, $opt_noop_ok, @opt_anchors);
+our ($opt_defaultcmd_interactive);
 
 our $us = qw(git-debrebase);
 
 sub badusage ($) {
     my ($m) = @_;
-    die "bad usage: $m\n";
+    print STDERR "bad usage: $m\n";
+    exit 12;
 }
 
 sub cfg ($;$) {
@@ -394,6 +396,15 @@ sub classify ($) {
        # BreakwaterStart commits are also anchors in the terminology
        # of git-debrebase(5), but they are untagged (and always
        # manually generated).
+       #
+       # We cannot not tolerate any tagged linear commit (ie,
+       # BreakwaterStart commits tagged `[anchor:') because such a
+       # thing could result from an erroneous linearising raw git
+       # rebase of a merge anchor.  That would represent a corruption
+       # of the branch. and we want to detect and reject the results
+       # of such corruption before it makes it out anywhere.  If we
+       # reject it here then we avoid making the pseudomerge which
+       # would be needed to push it.
 
        my $badanchor = sub { $unknown->("git-debrebase \`anchor' but @_"); };
        @p == 2 or return $badanchor->("has other than two parents");
@@ -905,8 +916,9 @@ sub cmd_launder_v0 () {
 }
 
 sub defaultcmd_rebase () {
+    push @ARGV, @{ $opt_defaultcmd_interactive // [] };
     my ($tip,$breakwater) = do_launder_head 'launder for rebase';
-    runcmd @git, qw(rebase), @ARGV, $breakwater;
+    runcmd @git, qw(rebase), @ARGV, $breakwater if @ARGV;
 }
 
 sub cmd_analyse () {
@@ -1071,6 +1083,21 @@ sub stitch ($$$$$) {
     update_head $old_head, $new_head, "stitch: $prose";
 }
 
+sub do_stitch ($) {
+    my ($prose) = @_;
+
+    my ($ffq_prev, $gdrlast, $ffq_prev_commitish) = ffq_prev_info();
+    if (!$ffq_prev_commitish) {
+       fail "No ffq-prev to stitch." unless $opt_noop_ok;
+       return;
+    }
+    my $dangling_head = get_head();
+
+    keycommits $dangling_head, \&snag, \&snag, \&snag;
+
+    stitch($dangling_head, $ffq_prev, $gdrlast, $ffq_prev_commitish, $prose);
+}
+
 sub cmd_new_upstream_v0 () {
     # automatically and unconditionally launders before rebasing
     # if rebase --abort is used, laundering has still been done
@@ -1216,6 +1243,10 @@ sub cmd_new_upstream_v0 () {
  "[git-debrebase anchor: new upstream $new_upstream_version, merge]",
             ];
 
+       my $clogsignoff = cmdoutput qw(git show),
+           '--pretty=format:%an <%ae>  %aD',
+           $new_bw;
+
        # Now we have to add a changelog stanza so the Debian version
        # is right.
        die if unlink "debian";
@@ -1232,7 +1263,7 @@ $p ($new_version) UNRELEASED; urgency=medium
 
   * Update to new upstream version $new_upstream_version.
 
- -- 
+ -- $clogsignoff
 
 END
        close CN or die $!;
@@ -1285,17 +1316,13 @@ sub cmd_stitch () {
     my $prose = 'stitch';
     GetOptions('prose=s', \$prose) or die badusage("bad options to stitch");
     badusage "no arguments allowed" if @ARGV;
+    do_stitch($prose);
+}
 
-    my ($ffq_prev, $gdrlast, $ffq_prev_commitish) = ffq_prev_info();
-    if (!$ffq_prev_commitish) {
-       fail "No ffq-prev to stitch." unless $opt_noop_ok;
-       return;
-    }
-    my $old_head = get_head();
-
-    keycommits $old_head, \&snag, \&snag, \&snag;
-
-    stitch($old_head, $ffq_prev, $gdrlast, $ffq_prev_commitish, $prose);
+sub cmd_conclude () {
+    badusage "no arguments allowed" if @ARGV;
+    do_launder_head 'launder for conclude';
+    do_stitch 'conclude';
 }
 
 sub cmd_convert_from_gbp () {
@@ -1449,7 +1476,19 @@ GetOptions("D+" => \$debuglevel,
           'noop-ok', => \$opt_noop_ok,
           'f=s' => \@snag_force_opts,
           'anchor=s' => \@opt_anchors,
-          'force!') or die badusage "bad options\n";
+          'force!',
+          '-i:s' => sub {
+              my ($opt,$val) = @_;
+              badusage "git-debrebase: no cuddling to -i for git-rebase"
+                  if length $val;
+              die if $opt_defaultcmd_interactive; # should not happen
+              $opt_defaultcmd_interactive = [ qw(-i) ];
+              # This access to @ARGV is excessive familiarity with
+              # Getopt::Long, but there isn't another sensible
+              # approach.  '-i=s{0,}' does not work with bundling.
+              push @$opt_defaultcmd_interactive, @ARGV;
+              @ARGV=();
+          }) or die badusage "bad options\n";
 initdebug('git-debrebase ');
 enabledebug if $debuglevel;
 
@@ -1460,7 +1499,7 @@ $rd = fresh_playground "$playprefix/misc";
 
 @opt_anchors = map { git_rev_parse $_ } @opt_anchors;
 
-if (!@ARGV || $ARGV[0] =~ m{^-}) {
+if (!@ARGV || $opt_defaultcmd_interactive || $ARGV[0] =~ m{^-}) {
     defaultcmd_rebase();
 } else {
     my $cmd = shift @ARGV;