X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=blobdiff_plain;f=git-debrebase;h=8c77dbccdcc1bc9c713983a30d33ba5cb2b730f4;hp=51b2429d3589a4bd2118f9e691a83b77578428c5;hb=ece8834f77855aab622f427ffc858e05917ca77d;hpb=7751e74d47b01d1271676e18103dfe7a65a2fe2a diff --git a/git-debrebase b/git-debrebase index 51b2429d..8c77dbcc 100755 --- a/git-debrebase +++ b/git-debrebase @@ -116,6 +116,7 @@ use Carp; use POSIX; use Data::Dumper; use Getopt::Long qw(:config posix_default gnu_compat bundling); +use Dpkg::Version; our ($opt_force); @@ -262,7 +263,7 @@ sub rm_subdir_cached ($) { sub read_tree_subdir ($$) { my ($subdir, $new_tree_object) = @_; rm_subdir_cached $subdir; - runcmd @git, qw(read-tree), "--prefix=$subdir/"; + runcmd @git, qw(read-tree), "--prefix=$subdir/", $new_tree_object; } # classify returns an info hash like this @@ -342,7 +343,7 @@ sub classify ($) { my $t = $r->{Tree}; foreach my $p (@p) { - $p->{Differs} => (get_differs $p->{CommitId}, $t), + $p->{Differs} = (get_differs $p->{CommitId}, $t), } printdebug "classify $objid \$t=$t \@p", @@ -373,7 +374,7 @@ sub classify ($) { } elsif ($d & (D_PAT_ADD|D_PAT_OTH)) { return $unknown->("edits debian/patches"); } elsif ($d & DS_DEB and !($d & ~DS_DEB)) { - my ($ty,$dummy) = git_cat_file "$ph[0]:debian"; + my ($ty,$dummy) = git_cat_file "$p[0]{CommitId}:debian"; if ($ty eq 'tree') { if ($d == D_DEB_CLOG) { return $classify->(qw(Changelog)); @@ -472,7 +473,7 @@ sub walk ($;$$); sub walk ($;$$) { my ($input, $nogenerate,$report) = @_; - # => ($tip, $breakwater_tip) + # => ($tip, $breakwater_tip, $last_upstream_merge_in_breakwater) # (or nothing, if $nogenerate) # go through commits backwards @@ -528,6 +529,8 @@ sub walk ($;$$) { no warnings qw(exiting); last; }; + my $last_upstream_update; + for (;;) { $cl = classify $cur; my $ty = $cl->{Type}; @@ -545,6 +548,7 @@ sub walk ($;$$) { $cur = $p0; next; } elsif ($ty eq 'BreakwaterStart') { + $last_upstream_update = $cur; $build_start->('FirstPackaging', $cur); } elsif ($ty eq 'Upstream') { push @upp_cl, $cl; @@ -569,6 +573,7 @@ sub walk ($;$$) { $cur = $contrib; next; } elsif ($ty eq 'BreakwaterUpstreamMerge') { + $last_upstream_update = $cur; $build_start->("PreviousBreakwater", $cur); } elsif ($ty eq 'DgitImportUnpatched') { my $pm = $pseudomerges[-1]; @@ -622,6 +627,7 @@ sub walk ($;$$) { $prline->(" Import"); $rewrite_from_here->(); $upp_limit //= $#upp_cl; # further, deeper, patches discarded + die 'BUG $upp_limit is not used anywhere?'; $cur = $ovwr; next; } else { @@ -727,6 +733,9 @@ sub walk ($;$$) { my $newcommit = cmdoutput @cmd; confess "$ch ?" unless $rewriting or $newcommit eq $cl->{CommitId}; $build = $newcommit; + if (grep { $method eq $_ } qw(DgitImportUpstreamUpdate)) { + $last_upstream_update = $cur; + } } }; @@ -734,7 +743,7 @@ sub walk ($;$$) { die sprintf "internal error %#x %s %s", $final_check, $build, $input if $final_check & ~D_PAT_ADD; - return ($build, $breakwater); + return ($build, $breakwater, $last_upstream_update); } sub get_head () { return git_rev_parse qw(HEAD); } @@ -776,6 +785,7 @@ sub cmd_analyse () { } sub cmd_new_upstream_v0 () { + # xxx would like to support more git-rebase options badusage "need NEW-VERSION UPS-COMMITISH [EXTRA-UPS-NAME EXTRA-UPS-COMMITISH...]" unless @ARGV % 2 == 0 and @ARGV >= 2; @@ -786,7 +796,7 @@ sub cmd_new_upstream_v0 () { my %pieces; # parse args - low commitment - my $new_version = (new Dpkg::Version scalar(shift @ARGV), 1); + my $new_version = (new Dpkg::Version scalar(shift @ARGV), check => 1); my $new_upstream_version = $new_version->version(); my $new_upstream = git_rev_parse shift @ARGV; @@ -803,14 +813,14 @@ sub cmd_new_upstream_v0 () { my @newpieces; my $newpiece = sub { my ($n, @x) = @_; # may be '' - $pc = $piece->($n, @x, NewIx => (scalar @newpieces)); + my $pc = $piece->($n, @x, NewIx => (scalar @newpieces)); push @newpieces, $pc; }; $newpiece->('', OldIx => 0, New => $new_upstream, - }; + ); while (@ARGV) { my $n = shift @ARGV; my $c = git_rev_parse shift @ARGV; @@ -820,11 +830,14 @@ sub cmd_new_upstream_v0 () { # now we need to investigate the branch this generates the # laundered version but we don't switch to it yet - my $old = get_head(); - my ($laundered_tip,$breakwater) = walk $old; + my $old_head = get_head(); + my ($old_laundered_tip,$old_bw,$old_upstream_update) = walk $old_head; - my $breakwater_cl = classify $breakwater; - my $old_orig = parsecommit $breakwater_cl->{OrigParents}[0]{CommitId}; + my $old_bw_cl = classify $old_bw; + my $old_upstream_update_cl = classify $old_upstream_update; + confess unless $old_upstream_update_cl->{OrigParents}; + my $old_upstream = parsecommit + $old_upstream_update_cl->{OrigParents}[0]{CommitId}; my $problems = 0; my $problem = sub { @@ -833,21 +846,21 @@ sub cmd_new_upstream_v0 () { print STDERR "preflight check failed: $msg\n"; }; - $piece->('', Old => $old_orig); + $piece->('', Old => $old_upstream); - if ($old_orig_ci =~ m{^\[git-debrebase }m) { - if ($old_orig_ci =~ - m{^\[git-debrebase combine-upstreams \.((?: $extra_orig_namepart_re)+)\]} + if ($old_upstream->{Msg} =~ m{^\[git-debrebase }m) { + if ($old_upstream->{Msg} =~ + m{^\[git-debrebase new-upstream combine \.((?: $extra_orig_namepart_re)+)\]} ) { my @oldpieces = ('', split / /, $1); - my $parentix = -1 + scalar @{ $old_orig->{Parents} }; - foreach my $i (0..$#$oldpieces) { + my $parentix = -1 + scalar @{ $old_upstream->{Parents} }; + foreach my $i (0..$#oldpieces) { my $n = $oldpieces[$i]; - $piece->($n, Old => $old_orig.'^'.$parentix); + $piece->($n, Old => $old_upstream->{CommitId}.'^'.$parentix); } } else { - $problem->("previous upstream $old_orig->{CommitId} is from". - " git-debrebase but not a \`combine-upstream' commit"); + $problem->("previous upstream $old_upstream->{CommitId} is from". + " git-debrebase but not a \`new-upstream combine' commit"); } } @@ -873,23 +886,22 @@ sub cmd_new_upstream_v0 () { } } + my $new_bw; + fresh_workarea(); in_workarea sub { my @upstream_merge_parents; if (!$problems) { - push @upstream_merge_parents, $old_orig->{CommitId}; + push @upstream_merge_parents, $old_upstream->{CommitId}; } foreach my $pc (@newpieces) { # always has '' first - my @cmd = @git, qw(read-tree); if ($pc->{Name}) { - push @cmd, "-prefix=$pcname/"; - runcmd @git, qw(rm --cached -rf --ignore-unmatch), $pcname; + read_tree_subdir $pc->{Name}, $pc->{New}; + } else { + runcmd @git, qw(read-tree), $pc->{New}; } - push @cmd, $pc->{New}; - runcmd @cmd; - push @upstream_merge_parents, $pc->{New}; } @@ -898,11 +910,11 @@ sub cmd_new_upstream_v0 () { if (@newpieces > 1) { # need to make the upstream subtree merge commit my $us_tree = cmdoutput @git, qw(write-tree); - my @cmd = @git, qw(commit-tree), $us_tree; + my @cmd = (@git, qw(commit-tree), $us_tree); push @cmd, qw(-p), $_ foreach @upstream_merge_parents; push @cmd, qw(-m), "Combine upstreams for $new_upstream_version"; push @cmd, qw(-m), - "[git-debrebase combine-upstreams . ". + "[git-debrebase new-upstream combine . ". (join " ", map { $_->{Name} } @newpieces[1..$#newpieces]). "]"; $new_upstream = cmdoutput @cmd; @@ -912,18 +924,62 @@ sub cmd_new_upstream_v0 () { # combined commit we just made. Either way it will be the # "upstream" parent of the breakwater special merge. - runcmd @git, qw(rm --cached -rf --ignore-unmatch), 'debian'; - runcmd @git, qw(read-tree --prefix=debian/), + read_tree_subdir 'debian', "$old_bw:debian"; + + # index now contains the breakwater merge contents + + my $bw_tree = cmdoutput @git, qw(write_tree); + my @cmd = (@git, qw(commit-tree), $bw_tree); + push @cmd, qw(-p), $old_bw, qw(-p), $new_upstream; + push @cmd, qw(-m), "Update to upstream $new_upstream_version"; + push @cmd, qw(-m), + "[git-debrebase new-upstream breakwater $new_upstream_version]"; + $new_bw = cmdoutput @git; + + # Now we have to add a changelog stanza so the Debian version + # is right. + + die if unlink "debian"; + die unless $!==ENOTEMPTY; + unlink "debian/changelog" or die $!; + open CN, ">", "debian/changelog" or die $!; + my $oldclog = git_cat_file ":debian/changelog"; + $oldclog =~ m/^($package_re) \(\S+\) / or + fail "cannot parse old changelog to get package name"; + my $p = $1; + print CN <