my @cmd = (@git, qw(diff-tree -z --no-renames));
push @cmd, @$opts;
push @cmd, "$_:" foreach $x, $y;
- push @cmd, @$limits;
+ push @cmd, '--', @$limits;
my $diffs = cmdoutput @cmd;
foreach (split /\0/, $diffs) { $fn->(); }
};
return $r;
};
+ my $claims_to_be_breakwater =
+ $r->{Msg} =~ m{^\[git-debrebase breakwater.*\]$}m;
+
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));
}
my @identical = grep { !$_->{Differs} } @p;
- if (@p == 2 && @identical == 1) {
+ 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)
+ ) {
my @overwritten = grep { $_->{Differs} } @p;
confess "internal error $objid ?" unless @overwritten==1;
return $classify->(qw(Pseudomerge),
my $cl;
my $xmsg = sub {
- my ($appendinfo) = @_;
+ my ($prose, $info) = @_;
my $ms = $cl->{Msg};
chomp $ms;
- $ms .= "\n\n[git-debrebase $appendinfo]\n";
+ $info //= '';
+ $ms .= "\n\n[git-debrebase$info: $prose]\n";
return (Msg => $ms);
};
my $rewrite_from_here = sub {
push @brw_cl, {
%$cl,
SpecialMethod => 'DgitImportUpstreamUpdate',
- $xmsg->("convert dgit import: upstream changes")
+ $xmsg->("convert dgit import: upstream changes",
+ " breakwater")
};
}
$prline->(" Import");
sub update_head_checkout ($$$) {
my ($old, $new, $mrest) = @_;
- my $symref = git_get_symref();
- runcmd @git, qw(checkout), $new, qw(.);
update_head $old, $new, $mrest;
+ runcmd @git, qw(reset --hard);
}
sub update_head_postlaunder ($$$) {
if ($old_upstream->{Msg} =~ m{^\[git-debrebase }m) {
if ($old_upstream->{Msg} =~
- m{^\[git-debrebase (?:\w*-)?upstream combine \.((?: $extra_orig_namepart_re)+)\]}
+ m{^\[git-debrebase upstream-combine \.((?: $extra_orig_namepart_re)+)\:.*\]$}m
) {
my @oldpieces = ('', split / /, $1);
my $parentix = -1 + scalar @{ $old_upstream->{Parents} };
}
} else {
fproblem "previous upstream $old_upstream->{CommitId} is from".
- " git-debrebase but not an \`upstream combine' commit";
+ " git-debrebase but not an \`upstream-combine' commit";
}
}
in_workarea sub {
my @upstream_merge_parents;
- if (!$problems) {
+ if (!$fproblems) {
push @upstream_merge_parents, $old_upstream->{CommitId};
}
# need to make the upstream subtree merge commit
$new_upstream = make_commit \@upstream_merge_parents,
[ "Combine upstreams for $new_upstream_version",
- ("[git-debrebase new-upstream combine . ".
- (join " ", map { $_->{Name} } @newpieces[1..$#newpieces]).
- "]"),
+ ("[git-debrebase upstream-combine . ".
+ (join " ", map { $_->{Name} } @newpieces[1..$#newpieces]).
+ ": new upstream]"),
];
}
# index now contains the breakwater merge contents
$new_bw = make_commit [ $old_bw, $new_upstream ],
[ "Update to upstream $new_upstream_version",
- "[git-debrebase new-upstream breakwater $new_upstream_version]",
+ "[git-debrebase breakwater: new upstream $new_upstream_version, merge]",
];
# Now we have to add a changelog stanza so the Debian version
# 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 changelog $new_upstream_version]",
+ "[git-debrebase: new upstream $new_upstream_version, changelog]",
];
};
# now it's for the user to sort out
}
+sub cmd_gbp2debrebase () {
+ badusage "needs 1 optional argument, the upstream" unless @ARGV<=1;
+ my ($upstream_spec) = @ARGV;
+ $upstream_spec //= 'refs/heads/upstream';
+ my $upstream = git_rev_parse $upstream_spec;
+ my $old_head = get_head();
+
+ my $upsdiff = get_differs $upstream, $old_head;
+ if ($upsdiff & D_UPS) {
+ runcmd @git, qw(--no-pager diff),
+ $upstream, $old_head,
+ qw( -- :!/debian :/);
+ fail "upstream ($upstream_spec) and HEAD are not identical in upstream files";
+ }
+
+ if (!is_fast_fwd $upstream, $old_head) {
+ fproblem "upstream ($upstream) is not an ancestor of HEAD";
+ } else {
+ my $wrong = cmdoutput
+ (@git, qw(rev-list --ancestry-path), "$upstream..HEAD",
+ qw(-- :/ :!/debian));
+ if (length $wrong) {
+ fproblem "history between upstream ($upstream) and HEAD contains direct changes to upstream files - are you sure this is a gbp (patches-unapplied) branch?";
+ print STDERR "list expected changes with: git log --stat --ancestry-path $upstream_spec..HEAD -- :/ ':!/debian'\n";
+ }
+ }
+
+ if ((git_cat_file "$upstream:debian")[0] ne 'missing') {
+ fproblem "upstream ($upstream) contains debian/ directory";
+ }
+
+ fproblems_maybe_bail();
+
+ my $work;
+
+ fresh_workarea();
+ in_workarea sub {
+ runcmd @git, qw(checkout -q -b gdr-internal), $old_head;
+ # make a branch out of the patch queue - we'll want this in a mo
+ runcmd qw(gbp pq import);
+ # strip the patches out
+ runcmd @git, qw(checkout -q gdr-internal~0);
+ rm_subdir_cached 'debian/patches';
+ $work = make_commit ['HEAD'], [
+ 'git-debrebase import: drop patch queue',
+ 'Delete debian/patches, as part of converting to git-debrebase format.',
+ '[git-debrebase: gbp2debrebase, drop patches]'
+ ];
+ # make the breakwater pseudomerge
+ # the tree is already exactly right
+ $work = make_commit [$work, $upstream], [
+ 'git-debrebase import: declare upstream',
+ 'First breakwater merge.',
+ '[git-debrebase breakwater: declare upstream]'
+ ];
+
+ # rebase the patch queue onto the new breakwater
+ runcmd @git, qw(reset --quiet --hard patch-queue/gdr-internal);
+ runcmd @git, qw(rebase --quiet --onto), $work, qw(gdr-internal);
+ $work = get_head();
+ };
+
+ update_head_checkout $old_head, $work, 'gbp2debrebase';
+}
+
sub cmd_downstream_rebase_launder_v0 () {
badusage "needs 1 argument, the baseline" unless @ARGV==1;
my ($base) = @ARGV;