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 $q ($base_q, reverse @input_qs) {
my $s = $q->{MR}{S};
gbp_pq_export "p-$s", $q->{SeriesBase}, $q->{SeriesTip};
+ my @earlier;
if (open S, $seriesfile) {
- my @earlier;
while (my $patch = <S>) {
chomp $patch or die $!;
$prereq{$patch} //= {};
"[git-debrebase merge-innards patch-queue prep:".
" $q->{SeriesTip}]"
];
+
+ read_tree_debian $newbase;
+ if (@earlier) {
+ read_tree_subdir 'debian/patches', "$pec:debian/patches";
+ } else {
+ rm_subdir_cached 'debian/patches';
+ }
+ $pec = make_commit [ $pec ], [
+ "Update debian/ (excluding patches) to final to avoid re-merging",
+ "debian/ was already merged and we need to just take that.",
+ "[git-debrebase merge-innards patch-queue packaging:".
+ " $q->{SeriesTip}]"
+ ];
+
printdebug "pec' $pec\n";
runcmd @git, qw(reset -q --hard), $pec;
$q->{MR}{PEC} = $pec;
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;
my $rewriting = 0;
+ my $read_tree_upstream = sub {
+ my ($treeish) = @_;
+ read_tree_upstream $treeish, 0, $build;
+ };
+
$#upp_cl = $upp_limit if defined $upp_limit;
my $committer_authline = calculate_committer_authline();
if ($method eq 'Debian') {
read_tree_debian($cltree);
} elsif ($method eq 'Upstream') {
- read_tree_upstream($cltree);
+ $read_tree_upstream->($cltree);
} elsif ($method eq 'StartRewrite') {
$rewriting = 1;
next;
confess unless $rewriting;
my $differs = (get_differs $build, $cltree);
next unless $differs & D_UPS;
- read_tree_upstream($cltree);
+ $read_tree_upstream->($cltree);
push @parents, map { $_->{CommitId} } @{ $cl->{OrigParents} };
} elsif ($method eq 'MergeCreateMergedBreakwaters') {
print "Found a general merge, will try to tidy it up.\n";
$rewriting = 1;
- read_tree_upstream($cl->{MergeBestAnchor});
- read_tree_upstream($cl->{MergeBestAnchor});
+ $read_tree_upstream->($cl->{MergeBestAnchor});
+ $read_tree_upstream->($cl->{MergeBestAnchor});
read_tree_debian($cltree);
@parents = map { $_->{Breakwater} } @{ $cl->{Parents} };
} elsif ($method eq 'MergeMergeSeries') {
$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 {