rm_subdir_cached 'debian/patches';
}
-sub read_tree_upstream ($;$) {
- my ($treeish, $keep_patches) = @_;
- my $save = cmdoutput @git, qw(write-tree --prefix=debian/);
+sub read_tree_upstream ($;$$) {
+ my ($treeish, $keep_patches, $tree_with_debian) = @_;
+ # if $tree_with_debian is supplied, will use that for debian/
+ # otherwise will save and restore it.
+ my $debian =
+ $tree_with_debian ? "$tree_with_debian:debian"
+ : cmdoutput @git, qw(write-tree --prefix=debian/);
runcmd @git, qw(read-tree), $treeish;
- read_tree_subdir 'debian', $save;
+ read_tree_subdir 'debian', $debian;
rm_subdir_cached 'debian/patches' unless $keep_patches;
};
foreach my $c (grep /./, split /\n/, cmdoutput @lcmd) {
my $commit = git_cat_file $c, 'commit';
printdebug "merge_series series ok, building $c\n";
- read_tree_upstream $c;
+ read_tree_upstream $c, 0, $newbase;
my $tree = cmdoutput @git, qw(write-tree);
$commit =~ s{^parent (\S+)$}{parent $build}m or confess;
$commit =~ s{^tree (\S+)$}{tree $tree}m or confess;
}
$result = $build;
runcmd @git, qw(update-ref refs/heads/result), $result;
+
+ runcmd @git, qw(checkout -q -b debug);
+ runcmd @git, qw(commit --allow-empty -q -m M-INDEX);
+ runcmd @git, qw(add .);
+ runcmd @git, qw(commit --allow-empty -q -m M-WORKTREE);
+ printdebug sprintf "merge_series done debug=%s\n",
+ git_rev_parse 'HEAD';
};
printdebug "merge_series returns $result\n";
return $result;
return $classify->("VanillaMerge");
}
-sub keycommits ($;$$$$) {
- my ($head, $furniture, $unclean, $trouble, $fatal) = @_;
+sub keycommits ($;$$$$$);
+
+sub mergedbreakwaters_anchor ($) {
+ my ($cl) = @_;
+ my $best_anchor;
+ foreach my $p (@{ $cl->{Parents} }) {
+ my ($panchor, $pbw) = keycommits $p->{CommitId},
+ undef,undef,undef,undef, 1;
+ $best_anchor = $panchor
+ if !defined $best_anchor
+ or is_fast_fwd $best_anchor, $panchor;
+ }
+ return $best_anchor;
+}
+
+sub keycommits ($;$$$$$) {
+ my ($head, $furniture, $unclean, $trouble, $fatal, $claimed_bw) = @_;
# => ($anchor, $breakwater)
# $unclean->("unclean-$tagsfx", $msg, $cl)
# $fatal is for unprocessable commits, and should normally cause
# a failure. If ignored, agaion, (undef, undef) is returned.
#
+ # If $claimed_bw, this is supposed to be a breakwater commit.
+ #
# If a callback is undef, fail is called instead.
# If a callback is defined but false, the situation is ignored.
# Callbacks may say:
# if the answer is no longer wanted.
my ($anchor, $breakwater);
+ $breakwater = $head if $claimed_bw;
my $clogonly;
my $cl;
my $found_pm;
$x->($trouble, 'vanillamerge',
"found vanilla merge"," ($head)");
return (undef,undef);
+ } elsif ($ty eq 'MergedBreakwaters') {
+ $found_anchor->(mergedbreakwaters_anchor $cl);
} else {
$x->($fatal, 'unprocessable',
"found unprocessable commit, cannot cope: $cl->{Why}",
push @brw_cl, {
%$cl,
SpecialMethod => 'MergeCreateMergedBreakwaters',
- $xmsg->('construct merged breakwater from vanilla merge'),
+ $xmsg->('constructed from vanilla merge',
+ ' merged-breakwater'),
};
push @upp_cl, {
%$cl,
$cl->{MergeInterchangeBaseInfo},
@{ $cl->{Parents} };
$last_anchor = $cl->{MergeBestAnchor};
- my $check_differs = get_differs $build, $cl->{CommitId};
+
+ # Check for mismerges:
+ my $check = sub {
+ my ($against, $allow, $what) = @_;
+ my $differs = get_differs $build, $against;
+ $nomerge->(sprintf
+ "merge misresolved: %s are not the same (%s %s d.%#x)",
+ $what, $against, $build, $differs)
+ if $differs & ~($allow | D_PAT_ADD);
+ };
+
# Breakwater changes which were in each side of the
- # merge should be in MergeCreateMergedBreakwaters
- # output. Upstream changes are exactly the result
- # of merge_series. So the only difference should
- # be potential laundry results.
- $nomerge->(sprintf
- "merge misresolved: tree is not the same (%s %s d.%#x)",
- $cl->{CommitId}, $build, $check_differs)
- if $check_differs & ~D_PAT_ADD;
+ # merge will have been incorporated into the
+ # MergeCreateMergedBreakwaters output. Because the
+ # upstream series was rebased onto the new breakwater,
+ # so should all of the packaging changes which were in
+ # the input.
+ $check->($input, D_UPS, 'debian files');
+
+ # Upstream files are merge_series, which ought to
+ # have been identical to the original merge.
+ $check->($cl->{CommitId}, DS_DEB, 'upstream files');
+
print "Merge resolution successful.\n";
next;
} else {