9 my $refs=`git-for-each-ref`;
14 my $gcfpid = open2 \*GCFO, \*GCFI, 'git cat-file --batch' or die $!;
17 my ($obj, $type) = @_;
18 print GCFI $obj, "\n" or die $!;
20 $x =~ m/^\w+ (\w+) (\d+)\n/ or die "$obj ?";
21 my ($gtype, $gsize) = ($1,$2,$3);
22 $gtype eq $type or die "$obj $gtype != $type ?";
24 read GFCO, $gdata, $gsize == $gsize or die "$obj $!";
26 $x eq "\n" or die "$obj $!";
33 sub rewrite_commit ($) {
35 my $m = \ $memo{$obj};
36 return $$m if defined $$m;
37 my $olddata = getobj $obj, 'commit';
38 die "$obj ?" unless $old;
39 $olddata =~ m/(?<=\n)(?=\n)/ or die "$obj ?";
42 s{^(parent )(\w+)$}{ $1 . rewrite_commit($2) }gme;
43 $count{fix_overwrite} += s{^commiter }{committer }gm;
44 if (!m{^author }m && !m{^committer }m) {
45 m{^parent (\w+)}m or die "$obj ?";
46 my $parent = getobj $1, 'commit';
47 $parent =~ m/^(?:.+\n)+(author .*\ncommitter .*\n)/;
48 m/\n$/ or die "$obj ?";
54 if ($newdata eq $olddata) {
57 my $gwopid = open2 \*GWO, \*GWI,
58 'git hash-object -t comit --stdin'
60 print GWI $newdata or die $!;
64 waitpid $gwopid,0 == $gwopid or die $!;
66 m/^(\w+)\n/ or die "$_ ?";
76 $_ = getobj $obj, 'tag';
77 m/^type (\w+)\n/m or die "$obj ?";
79 $count{"oddtags $1"}++;
82 m/^object (\w+)\n/m or die "$obj ?";
84 my $newref = rewrite_commit $oldref;
85 if ($oldref eq $newref) {
88 s/^(?<=object )\w+(?=\n)/$newref/m or die "$obj ?";
92 foreach my $rline (split /\n/, $refs) {
93 die "$_ ?" unless m/^(\w+)\s+(\w+)\s+(\S.*)/;
94 my ($obj, $type, $refname) = @_;
96 if ($type eq 'commit') {
97 $rewrite = rewrite_commit($obj);
98 } elsif ($type eq 'tag') {
99 my $rewrite = rewrite_tag($obj);
101 warn "ref $refname refers to $type\n";
104 next if $refname eq $rewrite;
105 push @updates, [ $refname, $rewrite ];
110 if git-symbolic-ref HEAD >/dev/null 2>&1; then
115 my $gfo = `LC_MESSAGES=C git fsck --no-dangling 2>&1`;
116 $? == 256 or die "$? $!"
121 m/^error in commit (\w+):.*invalid format - expected 'committer/;
123 case `wc -l <$tmp/bad` in
125 echo >&2 'nothing bad found - is git-fsck doing as we expect?' ;
129 nots="^$bads^0 ^$bads^1"
138 refs=`git-for-each-ref --format='%(refname)'`
140 if git-symbolic-ref HEAD >/dev/null 2>&1; then
144 for head in $refs; do
148 if git merge-base --is-ancestor $bad $head; then
153 if ! $needed; then continue; fi
157 git filter-branch --original dgit-badcommit --commit-filter '
162 sed -e '\''1,/^$/ s/^commiter /committer /'\''