git svn: make empty directory creation gc-aware
The "git svn gc" command creates and appends to unhandled.log.gz files which should be parsed before the uncompressed unhandled.log files. Reported-by: Robert Zeh Signed-off-by: Eric Wong <normalperson@yhbt.net>
Eric Wong committed
Dec 19, 2009 at 13:49 UTC
a5b80d92632a2d76325d4b6e6161022171a9fee4
2 files changed
+58
-11
git-svn.perl
+34
-11
@@ -2740,21 +2740,44 @@ sub do_fetch {
2740
2741
sub mkemptydirs {
2742
my ($self, $r) = @_;
2743
+
2744
+ sub scan {
2745
+ my ($r, $empty_dirs, $line) = @_;
2746
+ if (defined $r && $line =~ /^r(\d+)$/) {
2747
+ return 0 if $1 > $r;
2748
+ } elsif ($line =~ /^ \+empty_dir: (.+)$/) {
2749
+ $empty_dirs->{$1} = 1;
2750
+ } elsif ($line =~ /^ \-empty_dir: (.+)$/) {
2751
+ my @d = grep {m[^\Q$1\E(/|$)]} (keys %$empty_dirs);
2752
+ delete @$empty_dirs{@d};
2753
+ }
2754
+ 1; # continue
2755
+ };
2756
+
2757
my %empty_dirs = ();
2758
+ my $gz_file = "$self->{dir}/unhandled.log.gz";
2759
+ if (-f $gz_file) {
2760
+ if (!$can_compress) {
2761
+ warn "Compress::Zlib could not be found; ",
2762
+ "empty directories in $gz_file will not be read\n";
2763
+ } else {
2764
+ my $gz = Compress::Zlib::gzopen($gz_file, "rb") or
2765
+ die "Unable to open $gz_file: $!\n";
2766
+ my $line;
2767
+ while ($gz->gzreadline($line) > 0) {
2768
+ scan($r, \%empty_dirs, $line) or last;
2769
+ }
2770
+ $gz->gzclose;
2771
+ }
2772
+ }
2773
2745
- open my $fh, '<', "$self->{dir}/unhandled.log" or return;
2746
- binmode $fh or croak "binmode: $!";
2747
- while (<$fh>) {
2748
- if (defined $r && /^r(\d+)$/) {
2749
- last if $1 > $r;
2750
- } elsif (/^ \+empty_dir: (.+)$/) {
2751
- $empty_dirs{$1} = 1;
2752
- } elsif (/^ \-empty_dir: (.+)$/) {
2753
- my @d = grep {m[^\Q$1\E(/|$)]} (keys %empty_dirs);
2754
- delete @empty_dirs{@d};
2774
+ if (open my $fh, '<', "$self->{dir}/unhandled.log") {
2775
+ binmode $fh or croak "binmode: $!";
2776
+ while (<$fh>) {
2777
+ scan($r, \%empty_dirs, $_) or last;
2778
}
2779
+ close $fh;
2780
}
2757
- close $fh;
2781
2782
my $strip = qr/\A\Q$self->{path}\E(?:\/|$)/;
2783
foreach my $d (sort keys %empty_dirs) {
t/t9146-git-svn-empty-dirs.sh
+24
@@ -114,5 +114,29 @@ test_expect_success 'removed top-level directory does not exist' '
114
test ! -e removed/d
115
116
'
117
+unhandled=.git/svn/refs/remotes/git-svn/unhandled.log
118
+test_expect_success 'git svn gc-ed files work' '
119
+ (
120
+ cd removed &&
121
+ git svn gc &&
122
+ : Compress::Zlib may not be available &&
123
+ if test -f "$unhandled".gz
124
+ then
125
+ svn mkdir -m gz "$svnrepo"/gz &&
126
+ git reset --hard $(git rev-list HEAD | tail -1) &&
127
+ git svn rebase &&
128
+ test -f "$unhandled".gz &&
129
+ test -f "$unhandled" &&
130
+ for i in a b c "weird file name" gz "! !"
131
+ do
132
+ if ! test -d "$i"
133
+ then
134
+ echo >&2 "$i does not exist"
135
+ exit 1
136
+ fi
137
+ done
138
+ fi
139
+ )
140
+'
141
142
test_done