return () if $type eq 'missing';
}
+ $recurse = !!$recurse;
+
confess "get_tree needs object not $x ?" unless $x =~ m{^[0-9a-f]+\:};
our (@get_tree_memo, %get_tree_memo);
- my $memo = $get_tree_memo{$x};
+ my $memo = $get_tree_memo{$recurse,$x};
return @$memo if $memo;
local $Debian::Dgit::debugcmd_when_debuglevel = 3;
push @l, [ $n, $i ];
confess "$x need $last < $n ?" unless $last lt $n;
}
- $get_tree_memo{$x} = \@l;
+ $get_tree_memo{$recurse,$x} = \@l;
push @get_tree_memo, $x;
if (@get_tree_memo > 10) {
delete $get_tree_memo{ shift @get_tree_memo };
}
sub trees_diff_walk ($$$;$) {
- # trees_diff_walk [$all,] $x, $y, sub {... }
- # calls sub->($name, $ix, $iy) for each difference (with $all, each name)
+ # trees_diff_walk [{..opts...},] $x, $y, sub {... }
+ # calls sub->($name, $ix, $iy) for each difference
# $x and $y are as for get_tree
# where $name, $ix, $iy are $name and $info from get_tree
- my $all = shift @_ if @_>=4;
+ # opts are all call even for names same in both
+ # recurse call even for names same in both
+ my $opts = shift @_ if @_>=4;
my ($x,$y,$call) = @_;
+ my $all = $opts->{all};
return if !$all and $x eq $y;
- my @x = get_tree $x;
- my @y = get_tree $y;
+ my @x = get_tree $x, 0, $opts->{recurse};
+ my @y = get_tree $y, 0, $opts->{recurse};
printdebug "trees_diff_walk(..$x,$y..) ".Dumper(\@x,\@y)
if $debuglevel >= 3;
while (@x || @y) {
my $xp = $ix && "$xd/patches";
my $yp = $iy && "$yd/patches";
- trees_diff_walk $xp, $yp, sub {
+ trees_diff_walk { recurse=>1 }, $xp, $yp, sub {
my ($n,$ix,$iy) = @_;
# analyse difference in debian/patches
my $ok;
- if ($n !~ m/\.series$/s && !$ix && $plain->($iy)) {
+ if ($n =~ m{/$}s) {
+ # we are recursing; directories may appear and disappear
+ $ok = 1;
+ } elsif ($n !~ m/\.series$/s && !$ix && $plain->($iy)) {
$ok = 1;
} elsif ($n eq 'series' && $plain->($ix) && $plain->($iy)) {
my $x_s = (git_cat_file "$xp/series", 'blob');
push @deferred_updates, "update $gdrlast $newvalue $oldvalue";
}
+sub fail_unprocessable ($) {
+ my ($msg) = @_;
+ changedir $maindir;
+ my ($ffqs, $ffqm, $symref, $ffq_prev, $gdrlast) = ffq_prev_branchinfo();
+
+ my $mangled = <<END;
+Branch/history seems mangled - no longer in gdr format.
+See ILLEGAL OPERATIONS in git-debrebase(5).
+END
+ chomp $mangled;
+
+ if (defined $ffqm) {
+ fail <<END;
+$msg
+Is this meant to be a gdr branch? $ffqm
+END
+ } elsif (git_get_ref $ffq_prev) {
+ fail <<END;
+$msg
+$mangled
+Consider git-debrebase scrap, to throw away your recent work.
+END
+ } elsif (!git_get_ref $gdrlast) {
+ fail <<END;
+$msg
+Branch does not seem to be meant to be a git-debrebase branch?
+Wrong branch, or maybe you needed git-debrebase convert-from-*.
+END
+ } elsif (is_fast_fwd $gdrlast, git_rev_parse 'HEAD') {
+ fail <<END;
+$msg
+$mangled
+END
+ } else {
+ fail <<END;
+$msg
+Branch/history mangled, and diverged since last git-debrebase.
+Maybe you reset to, or rebased from, somewhere inappropriate.
+END
+ }
+};
+
sub gbp_pq_export ($$$) {
my ($bname, $base, $tip) = @_;
# must be run in a workarea. $bname and patch-queue/$bname
my $clogonly;
my $cl;
my $found_pm;
- $fatal //= sub { fail $_[1]; };
+ $fatal //= sub { fail_unprocessable $_[1]; };
my $x = sub {
my ($cb, $tagsfx, $mainwhy, $xwhy) = @_;
my $why = $mainwhy.$xwhy;
my ($prose, $info) = @_;
my $ms = $cl->{Msg};
chomp $ms;
- $info //= '';
- $ms .= "\n\n[git-debrebase$info: $prose]\n";
+ confess unless defined $info;
+ $ms .= "\n\n[git-debrebase $info: $prose]\n";
return (Msg => $ms);
};
my $rewrite_from_here = sub {
if ($nogenerate) {
return (undef,undef);
}
- fail "found unprocessable commit, cannot cope".
+ fail_unprocessable "found unprocessable commit, cannot cope".
(defined $cl->{Why} ? "; $cl->{Why}:": ':').
" (commit $cur) (d.".
(join ' ', map { sprintf "%#x", $_->{Differs} }
} elsif ($ty eq 'Mixed') {
my $queue = sub {
my ($q, $wh) = @_;
- my $cls = { %$cl, $xmsg->("split mixed commit: $wh part") };
+ my $cls = { %$cl, $xmsg->("mixed commit: $wh part",'split') };
push @$q, $cls;
};
$queue->(\@brw_cl, "debian");
push @brw_cl, {
%$cl,
SpecialMethod => 'DgitImportDebianUpdate',
- $xmsg->("convert dgit import: debian changes")
+ $xmsg->("debian changes", 'convert dgit import')
}, {
%$cl,
SpecialMethod => 'DgitImportUpstreamUpdate',
$xmsg->("convert dgit import: upstream update",
- " anchor")
+ "anchor")
};
$prline->(" Import");
$rewrite_from_here->(\@brw_cl);
%$cl,
SpecialMethod => 'MergeCreateMergedBreakwaters',
$xmsg->('constructed from vanilla merge',
- ' merged-breakwater'),
+ 'merged-breakwater'),
};
push @upp_cl, {
%$cl,
# Now we have the final new breakwater branch in the index
$new_bw = make_commit [ $new_bw ],
[ "Update changelog for new upstream $new_upstream_version",
- "[git-debrebase: new upstream $new_upstream_version, changelog]",
+ "[git-debrebase changelog: new upstream $new_upstream_version]",
];
};
read_tree_subdir 'debian/patches', $ptree;
$out = make_commit [$head], [
'Commit patch queue (exported by git-debrebase)',
- '[git-debrebase: export and commit patches]',
+ '[git-debrebase make-patches: export and commit patches]',
];
};
return $out;
[qw(blob missing)];
$series //= '';
my %series;
+ our $comments_snagged;
foreach my $f (grep /\S/, grep {!m/^\s\#/} split /\n/, $series) {
+ if ($f =~ m/^\s*\#/) {
+ snag 'series-comments',
+ "$seriesfn contains comments, which will be discarded"
+ unless $comments_snagged++;
+ next;
+ }
fail "patch $f repeated in $seriesfn !" if $series{$f}++;
}
foreach my $patchfile (get_tree "$head:debian/patches", 1,1) {
END
This includes the contents of the .orig(s), minus any debian/ directory.
-[git-debrebase import-from-dgit-view upstream-import-convert: $version]
+[git-debrebase convert-from-dgit-view upstream-import-convert: $version]
END
];
push @upstreams, { Commit => $ups_synth,
'git-debrebase convert-from-dgit-view: drop upstream changes from breakwater',
"Drop upstream changes, and delete debian/patches, as part of converting\n".
"to git-debrebase format. Upstream changes will appear as commits.",
- '[git-debrebase convert-from-dgit-view: drop patches from tree]'
+ '[git-debrebase convert-from-dgit-view drop-patches]'
];
}
$work = make_commit [ $work, $u->{Commit} ], [
'convert-from-dgit-view';
}
+sub cmd_forget_was_ever_debrebase () {
+ badusage "forget-was-ever-debrebase takes no further arguments" if @ARGV;
+ my ($ffqstatus, $ffq_msg, $current, $ffq_prev, $gdrlast) =
+ ffq_prev_branchinfo();
+ fail "Not suitable for recording git-debrebaseness anyway: $ffq_msg"
+ if defined $ffq_msg;
+ push @deferred_updates, "delete $ffq_prev";
+ push @deferred_updates, "delete $gdrlast";
+ snags_maybe_bail();
+ run_deferred_updates "forget-was-ever-debrebase";
+}
+
sub cmd_record_resolved_merge () {
badusage "record-resolved-merge takes no further arguments" if @ARGV;
# MERGE-TODO needs documentation