From: Eric Wong Date: Wed, 7 Feb 2007 19:50:16 +0000 (-0800) Subject: git-svn: run get_log() on a sub-directory if possible X-Git-Tag: v1.5.1-rc1~189 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=d2ae14346c71d57c57dc7b1c1f8272c09f51ccf9;p=git.git git-svn: run get_log() on a sub-directory if possible This is an optimization that should conserve network bandwidth on certain repositories and configurations. Signed-off-by: Eric Wong --- diff --git a/git-svn.perl b/git-svn.perl index d0bde71f2..5e1a64c6d 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -2433,21 +2433,62 @@ sub gs_fetch_loop_common { my ($self, $base, $head, @gs) = @_; my $inc = 1000; my ($min, $max) = ($base, $head < $base + $inc ? $head : $base + $inc); + + my %common; foreach my $gs (@gs) { if (my $last_commit = $gs->last_commit) { $gs->assert_index_clean($last_commit); } + my @tmp = split m#/#, $gs->{path}; + my $p = ''; + foreach (@tmp) { + $p .= length($p) ? "/$_" : $_; + $common{$p} ||= 0; + $common{$p}++; + } + } + my $longest_path = ''; + foreach (sort {length $b <=> length $a} keys %common) { + if ($common{$_} == @gs) { + $longest_path = $_; + last; + } } while (1) { my %revs; + my $err; my $err_handler = $SVN::Error::handler; - $SVN::Error::handler = \&skip_unknown_revs; - $self->get_log([''], $min, $max, 0, 1, 1, sub { - my ($paths, $r, $author, $date, $log) = @_; - $revs{$r} = [ dup_changed_paths($paths), - { author => $author, - date => $date, - log => $log } ] }); + $SVN::Error::handler = sub { + ($err) = @_; + skip_unknown_revs($err); + }; + sub _cb { + my ($paths, $r, $author, $date, $log) = @_; + [ dup_changed_paths($paths), + { author => $author, date => $date, log => $log } ]; + } + $self->get_log([$longest_path], $min, $max, 0, 1, 1, + sub { $revs{$_[1]} = _cb(@_) }); + if ($err && $max >= $head) { + print STDERR "Path '$longest_path' ", + "was probably deleted:\n", + $err->expanded_message, + "\nWill attempt to follow ", + "revisions r$min .. r$max ", + "committed before the deletion\n"; + my $hi = $max; + while (--$hi >= $min) { + my $ok; + $self->get_log([$longest_path], $min, $hi, + 0, 1, 1, sub { + $ok ||= $_[1]; + $revs{$_[1]} = _cb(@_) }); + if ($ok) { + print STDERR "r$min .. r$ok OK\n"; + last; + } + } + } $SVN::Error::handler = $err_handler; foreach my $r (sort {$a <=> $b} keys %revs) {