# git-debrebase [<options> --] [<git-rebase options...>]
# git-debrebase [<options>] analyse
# git-debrebase [<options>] breakwater # prints breakwater tip only
-# git-debrebase [<options>] launder # prints breakwater tip etc.
# git-debrebase [<options>] stitch [--prose=<for commit message>]
+# git-debrebase [<options>] launder-v0 # prints breakwater tip etc.
# git-debrebase [<options>] downstream-rebase-launder-v0 # experimental
#
# git-debrebase [<options>] convert-from-gbp [<upstream-git-rev>]
fail "missing required git config $k" unless $optional;
return ();
}
- return split /\0/, $out;
+ my @l = split /\0/, $out;
+ return wantarray ? @l : $l[0];
}
memoize('cfg');
# has additional entry in classification result
# OrigParents = [ subset of Parents ]
#
-# BreakwaterUpstreamMerge
+# Anchor
# has additional entry in classification result
# OrigParents = [ subset of Parents ] # singleton list
#
+# BreakwaterStart
+#
# Unknown
# has additional entry in classification result
# Why => "prose"
return $r;
};
- my $claims_to_be_breakwater =
- $r->{Msg} =~ m{^\[git-debrebase breakwater.*\]$}m;
+ 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;
+
+ if ($r->{Msg} =~ m{^\[git-debrebase anchor.*\]$}m) {
+ # multi-orig upstreams are represented with an anchor merge
+ # from a single upstream commit which combines the orig tarballs
+
+ 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");
+
+ # How to decide about l/r ordering of anchors ? git
+ # --topo-order prefers to expand 2nd parent first. There's
+ # already an easy rune to look for debian/ history anyway (git log
+ # debian/) so debian breakwater branch should be 1st parent; that
+ # way also there's also an easy rune to look for the upstream
+ # patches (--topo-order).
+
+ $p[0]{IsOrigin} and $badanchor->("is an origin commit");
+ $p[1]{Differs} & ~DS_DEB and
+ $badanchor->("upstream files differ from left parent");
+ $p[0]{Differs} & ~D_UPS and
+ $badanchor->("debian/ differs from right parent");
+
+ return $classify->(qw(Anchor),
+ OrigParents => [ $p[1] ]);
+ }
if (@p == 1) {
- if ($claims_to_be_breakwater) {
- return $unknown->("single-parent git-debrebase breakwater \`merge'");
- }
my $d = $r->{Parents}[0]{Differs};
if ($d == D_PAT_ADD) {
return $classify->(qw(AddPatches));
return $unknown->("origin commit");
}
- my @identical = grep { !$_->{Differs} } @p;
- if (@p == 2 && @identical == 1 && !$claims_to_be_breakwater
- # breakwater merges can look like pseudomerges, if they are
- # "declare" commits (ie, there are no upstream changes)
- ) {
+ if (@p == 2 && @identical == 1) {
my @overwritten = grep { $_->{Differs} } @p;
confess "internal error $objid ?" unless @overwritten==1;
return $classify->(qw(Pseudomerge),
OrigParents => \@orig_ps);
}
- my ($stype, $series) = git_cat_file "$t:debian/patches/series";
- my $haspatches = $stype ne 'missing' && $series =~ m/^\s*[^#\n\t ]/m;
-
- # How to decide about l/r ordering of breakwater merges ? git
- # --topo-order prefers to expand 2nd parent first. There's
- # already an easy rune to look for debian/ history anyway (git log
- # debian/) so debian breakwater branch should be 1st parent; that
- # way also there's also an easy rune to look for the upstream
- # patches (--topo-order).
-
- # The above tells us which way *we* will generate them. But we
- # might encounter ad-hoc breakwater merges generated manually,
- # which might be the other way around. In principle, in some odd
- # situations, a breakwater merge might have two identical parents.
- # In that case we guess which way round it is (ie, which parent
- # has the upstream history). The order of the 2-iteration loop
- # controls which guess we make.
-
- foreach my $prevbrw (qw(0 1)) {
- if (@p == 2 &&
- !$haspatches &&
- !$p[$prevbrw]{IsOrigin} && # breakwater never starts with an origin
- !($p[!$prevbrw]{Differs} & ~DS_DEB) && # no non-debian changess
- !($p[$prevbrw]{Differs} & ~D_UPS)) { # no non-upstream changes
- return $classify->(qw(BreakwaterUpstreamMerge),
- OrigParents => [ $p[!$prevbrw] ]);
- }
- }
-
- # multi-orig upstreams are represented with a breakwater merge
- # from a single upstream commit which combines the orig tarballs
-
return $unknown->("complex merge");
}
if ($ty eq 'Packaging' or
$ty eq 'Changelog') {
$breakwater //= $head;
- } elsif ($ty eq 'BreakwaterUpstreamMerge' or
+ } elsif ($ty eq 'Anchor' or
$ty eq 'BreakwaterStart') {
$breakwater //= $head;
last;
sub walk ($;$$) {
my ($input,
$nogenerate,$report) = @_;
- # => ($tip, $breakwater_tip, $last_upstream_merge_in_breakwater)
+ # => ($tip, $breakwater_tip, $last_anchor)
# (or nothing, if $nogenerate)
printdebug "*** WALK $input ".($nogenerate//0)." ".($report//'-')."\n";
no warnings qw(exiting); last;
};
- my $last_upstream_update;
+ my $last_anchor;
for (;;) {
$cl = classify $cur;
$cur = $p0;
next;
} elsif ($ty eq 'BreakwaterStart') {
- $last_upstream_update = $cur;
+ $last_anchor = $cur;
$build_start->('FirstPackaging', $cur);
} elsif ($ty eq 'Upstream') {
push @upp_cl, $cl;
$rewrite_from_here->();
$cur = $contrib;
next;
- } elsif ($ty eq 'BreakwaterUpstreamMerge') {
- $last_upstream_update = $cur;
- $build_start->("PreviousBreakwater", $cur);
+ } elsif ($ty eq 'Anchor') {
+ $last_anchor = $cur;
+ $build_start->("Anchor", $cur);
} elsif ($ty eq 'DgitImportUnpatched') {
my $pm = $pseudomerges[-1];
if (defined $pm) {
%$cl,
SpecialMethod => 'DgitImportUpstreamUpdate',
$xmsg->("convert dgit import: upstream update",
- " breakwater")
+ " anchor")
};
$prline->(" Import");
$rewrite_from_here->();
confess "$ch ?" unless $rewriting or $newcommit eq $cl->{CommitId};
$build = $newcommit;
if (grep { $method eq $_ } qw(DgitImportUpstreamUpdate)) {
- $last_upstream_update = $cur;
+ $last_anchor = $cur;
}
}
};
die sprintf "internal error %#x %s %s", $final_check, $build, $input
if $final_check & ~D_PAT_ADD;
- my @r = ($build, $breakwater, $last_upstream_update);
+ my @r = ($build, $breakwater, $last_anchor);
printdebug "*** WALK RETURN @r\n";
return @r
}
runcmd @git, qw(rm --quiet --ignore-unmatch -rf debian/patches);
}
-sub cmd_launder () {
- badusage "no arguments to launder allowed" if @ARGV;
+sub cmd_launder_v0 () {
+ badusage "no arguments to launder-v0 allowed" if @ARGV;
my $old = get_head();
- my ($tip,$breakwater,$last_upstream_merge) = walk $old;
+ my ($tip,$breakwater,$last_anchor) = walk $old;
update_head_postlaunder $old, $tip, 'launder';
printf "# breakwater tip\n%s\n", $breakwater;
printf "# working tip\n%s\n", $tip;
- printf "# last upstream merge\n%s\n", $last_upstream_merge;
+ printf "# last anchor\n%s\n", $last_anchor;
}
sub defaultcmd_rebase () {
return ('weird-symref', 'HEAD symref is not to refs/')
unless $current =~ m{^refs/};
my $ffq_prev = "refs/$ffq_refprefix/$'";
+ printdebug "ffq_prev_branchinfo branch current $current\n";
return ('branch', undef, $current, $ffq_prev);
}
my @check_specs = split /\;/, (cfg "branch.$branch.ffq-ffrefs",1) // '*';
my %checked;
+ printdebug "ffq check_specs @check_specs\n";
+
my $check = sub {
my ($lrref, $desc) = @_;
+ printdebug "ffq might check $lrref ($desc)\n";
my $invert;
for my $chk (@check_specs) {
my $glob = $chk;
- $invert = $glob =~ s{^[^!]}{};
+ $invert = $glob =~ s{^[!^]}{};
last if fnmatch $glob, $lrref;
}
return if $invert;
if (is_fast_fwd $lrval, $currentval) {
print "OK, you are ahead of $lrref\n" or die $!;
$checked{$lrref} = 1;
- } if (is_fast_fwd $currentval, $lrval) {
+ } elsif (is_fast_fwd $currentval, $lrval) {
$checked{$lrref} = -1;
fproblem 'behind', "you are behind $lrref, divergence risk";
} else {
};
my $merge = cfg "branch.$branch.merge",1;
- if (defined $merge && $merge =~ m{^refs/heads/}) {
+ if (defined $merge and $merge =~ m{^refs/heads/}) {
my $rhs = $';
+ printdebug "ffq merge $rhs\n";
my $check_remote = sub {
- my ($remote, $desc) = (@_);
+ my ($remote, $desc) = @_;
+ printdebug "ffq check_remote ".($remote//'undef')." $desc\n";
return unless defined $remote;
$check->("refs/remotes/$remote/$rhs", $desc);
};
- $check_remote->((cfg "branch.$branch.remote",1),
+ $check_remote->((scalar cfg "branch.$branch.remote",1),
'remote fetch/merge branch');
- $check_remote->((cfg "branch.$branch.pushRemote",1) //
- (cfg "branch.$branch.pushDefault",1),
+ $check_remote->((scalar cfg "branch.$branch.pushRemote",1) //
+ (scalar cfg "branch.$branch.pushDefault",1),
'remote push branch');
}
if ($branch =~ m{^dgit/}) {
- $check->("remotes/dgit/$branch", 'remote dgit branch');
+ $check->("refs/remotes/dgit/$branch", 'remote dgit branch');
} elsif ($branch =~ m{^master$}) {
- $check->("remotes/dgit/dgit/sid", 'remote dgit branch for sid');
+ $check->("refs/remotes/dgit/dgit/sid", 'remote dgit branch for sid');
}
fproblems_maybe_bail();
# $new_upstream is either the single upstream commit, or the
# combined commit we just made. Either way it will be the
- # "upstream" parent of the breakwater special merge.
+ # "upstream" parent of the anchor merge.
read_tree_subdir 'debian', "$old_bw:debian";
- # index now contains the breakwater merge contents
+ # index now contains the anchor merge contents
$new_bw = make_commit [ $old_bw, $new_upstream ],
[ "Update to upstream $new_upstream_version",
- "[git-debrebase breakwater: new upstream $new_upstream_version, merge]",
+ "[git-debrebase anchor: new upstream $new_upstream_version, merge]",
];
# Now we have to add a changelog stanza so the Debian version
'Delete debian/patches, as part of converting to git-debrebase format.',
'[git-debrebase convert-from-gbp: drop patches from tree]'
];
- # make the breakwater pseudomerge
+ # make the anchor merge
# the tree is already exactly right
$work = make_commit [$work, $upstream], [
'git-debrebase import: declare upstream',
'First breakwater merge.',
- '[git-debrebase breakwater: declare upstream]'
+ '[git-debrebase anchor: declare upstream]'
];
# rebase the patch queue onto the new breakwater