X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=badcommit-fixup;h=4573121076bac4ee3b094d9a0b04b9d7fa3e2605;hb=f773b1ed2796196e0fa801886fce493544c38fe0;hp=1fa95d5fc31009f9a2ffd22e155d3e282abe43f9;hpb=e9908f95e2c7ada1196b1aea544dc3c451c04f7b;p=dgit.git diff --git a/badcommit-fixup b/badcommit-fixup index 1fa95d5f..45731210 100755 --- a/badcommit-fixup +++ b/badcommit-fixup @@ -10,10 +10,19 @@ use POSIX; use IPC::Open2; use Data::Dumper; -die unless "@ARGV" eq "--test" or "@ARGV" eq "--real"; +my $real; -my ($modeopt) = @ARGV; -my $real = ($modeopt eq '--real'); +foreach my $a (@ARGV) { + if ($a eq '--test') { + $real = 0; + } elsif ($a eq '--real') { + $real = 1; + } else { + die "$a ?"; + } +} + +die unless defined $real; my $gcfpid = open2 \*GCFO, \*GCFI, 'git cat-file --batch' or die $!; @@ -21,6 +30,15 @@ our %count; no warnings qw(recursion); +sub runcmd { + system @_ and die "@_ $! $?"; +} + +$!=0; $?=0; +my $bare = `git rev-parse --is-bare-repository`; +die "$? $!" if $?; +chomp $bare or die; + sub getobj ($$) { my ($obj, $type) = @_; print GCFI $obj, "\n" or die $!; @@ -29,7 +47,6 @@ sub getobj ($$) { $gtype eq $type or die "$obj $gtype != $type ?"; my $gdata; (read GCFO, $gdata, $gsize) == $gsize or die "$obj $!"; -#print STDERR ">$obj|$x|$gdata|$gsize<\n"; $x = ; $x eq "\n" or die "$obj ($_) $!"; $count{inspected}++; @@ -62,7 +79,7 @@ sub rewrite_commit ($) { my $olddata = getobj $obj, 'commit'; $olddata =~ m/(?<=\n)(?=\n)/ or die "$obj ?"; my $msg = $'; - $_ = $`; + local $_ = $`; s{^(parent )(\w+)$}{ $1 . rewrite_commit($2) }gme; $count{'fix overwrite'} += s{^commiter }{committer }gm; if (!m{^author }m && !m{^committer }m) { @@ -85,6 +102,72 @@ sub rewrite_commit ($) { return $newobj; } +sub rewrite_commit_adddummy ($$$) { + my ($ref, $veryold, $old) = @_; + + die "$bare ?" unless $bare eq 'true'; + + my $td = 'dgit-broken-fixup.tmp'; + runcmd qw(rm -rf), $td; + mkdir $td, 0700 or die "$td $!"; + chdir $td or die $!; + runcmd qw(git init -q); + runcmd qw(git config gc.auto 0); + runcmd qw(rm -rf .git/objects); + symlink "../../objects", ".git/objects" or die $!; + runcmd qw(git checkout -q), $old; + + open C, "debian/changelog" or die $!; + my $clog = do { + local $/ = undef; + ; + }; + C->error and die $!; + close C or die $!; + defined $clog or die $!; + + $!=0; $?=0; + my $v = `dpkg-parsechangelog`; + die "$ref $veryold $old $? $!" if $?; + $v =~ m/^Source: (\S+)$/m or die "$ref $veryold $old ?"; + my $pkg = $1; + $v =~ m/^Version: (\S+)$/m or die "$ref $veryold $old ?"; + my $vsn = $1; + $vsn .= "+~dgitfix"; + + open C, ">", "debian/changelog" or die $!; + print C < Thu, 05 Jan 2017 17:58:21 +0000 + +END + print C $clog or die $!; + close C or die $!; + + runcmd qw(git commit -q), + '--author=Ian Jackson ', + qw(-m), 'Dummy changelog entry to work around #849041 fallout', + qw(debian/changelog); + + $!=0; $?=0; + my $new = `git rev-parse HEAD`; + die "$? $!" if $?; + chomp $new or die; + + chdir '..' or die $!; + runcmd qw(rm -rf), $td; + + $count{dummyadded}++; + + return $new; +} + sub rewrite_tag ($) { my ($obj) = @_; $_ = getobj $obj, 'tag'; @@ -119,6 +202,10 @@ foreach my $rline (split /\n/, $refs) { my $rewrite; if ($type eq 'commit') { $rewrite = rewrite_commit($obj); + if ($refname =~ m{^refs/dgit/[^/]+$} && + $rewrite ne $obj) { + $rewrite = rewrite_commit_adddummy $refname, $obj, $rewrite; + } } elsif ($type eq 'tag') { $rewrite = rewrite_tag($obj); } else { @@ -129,11 +216,15 @@ foreach my $rline (split /\n/, $refs) { push @updates, [ $refname, $obj, $rewrite ]; } +our $worktree; + +#print Dumper(\@updates); + open U, "|git update-ref -m 'dgit bad commit fixup' --stdin" or die $!; -if ($real) { +if ($real && $bare eq 'false') { print "detaching your HEAD\n" or die $!; - system 'git checkout --detach' and die "$! $?"; + runcmd 'git checkout --detach'; } for my $up (@updates) {