git-svn: avoid fetching files twice in the same revision
authorEric Wong <normalperson@yhbt.net>
Sun, 3 Dec 2006 00:19:31 +0000 (16:19 -0800)
committerJunio C Hamano <junkio@cox.net>
Sun, 3 Dec 2006 01:25:34 +0000 (17:25 -0800)
SVN is not entirely consistent in returning log information and
sometimes returns file information when adding subdirectories,
and sometimes it does not (only returning information about the
directory that was added).  This caused git-svn to occasionally
add a file to the list of files to be fetched twice.  Now we
change the data structure to be hash to avoid repeated fetches.

As of now (in master), this only affects repositories fetched
without deltas enabled (file://, and when manually overriden
with GIT_SVN_DELTA_FETCH=0); so this bug mainly affects users of
1.4.4.1 and maint.

Thanks to Florian Weimer for reporting this bug.

[jc: backported for maint]

Signed-off-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
git-svn.perl

index bb8935afe6ab9eb67ae19b13a040cebe54246c37..b53273eaea77c80fbfc3e1791a5eeab16c1b4c7e 100755 (executable)
@@ -2778,7 +2778,7 @@ sub process_rm {
 sub libsvn_fetch {
        my ($last_commit, $paths, $rev, $author, $date, $msg) = @_;
        open my $gui, '| git-update-index -z --index-info' or croak $!;
-       my @amr;
+       my %amr;
        foreach my $f (keys %$paths) {
                my $m = $paths->{$f}->action();
                $f =~ s#^/+##;
@@ -2792,7 +2792,7 @@ sub libsvn_fetch {
                my $t = $SVN->check_path($f, $rev, $pool);
                if ($t == $SVN::Node::file) {
                        if ($m =~ /^[AMR]$/) {
-                               push @amr, [ $m, $f ];
+                               $amr{$f} = $m;
                        } else {
                                die "Unrecognized action: $m, ($f r$rev)\n";
                        }
@@ -2800,13 +2800,13 @@ sub libsvn_fetch {
                        my @traversed = ();
                        libsvn_traverse($gui, '', $f, $rev, \@traversed);
                        foreach (@traversed) {
-                               push @amr, [ $m, $_ ]
+                               $amr{$_} = $m;
                        }
                }
                $pool->clear;
        }
-       foreach (@amr) {
-               libsvn_get_file($gui, $_->[1], $rev, $_->[0]);
+       foreach (keys %amr) {
+               libsvn_get_file($gui, $_, $rev, $amr{$_});
        }
        close $gui or croak $?;
        return libsvn_log_entry($rev, $author, $date, $msg, [$last_commit]);