git-svn: memoize conversion of SVN merge ticket info to git commit ranges
Each time the svn mergeinfo ticket changes, we look it up in the rev_map; when there are a lot of merged branches, this will result in many repeated lookups of the same information for subsequent commits. Arrange the slow part of the function so that it may be memoized, and memoize it. The more expensive revision walking operation can be memoized separately. [ew: changed "next" to "return" for function exit] Signed-off-by: Sam Vilain <sam@vilain.net> Acked-by: Eric Wong <normalperson@yhbt.net>maint
parent
1d144aa25e
commit
7d944c3399
53
git-svn.perl
53
git-svn.perl
|
@ -1634,6 +1634,7 @@ use Carp qw/croak/;
|
|||
use File::Path qw/mkpath/;
|
||||
use File::Copy qw/copy/;
|
||||
use IPC::Open3;
|
||||
use Memoize; # core since 5.8.0, Jul 2002
|
||||
|
||||
my ($_gc_nr, $_gc_period);
|
||||
|
||||
|
@ -2994,42 +2995,33 @@ sub find_extra_svk_parents {
|
|||
}
|
||||
}
|
||||
|
||||
# note: this function should only be called if the various dirprops
|
||||
# have actually changed
|
||||
sub find_extra_svn_parents {
|
||||
my ($self, $ed, $mergeinfo, $parents) = @_;
|
||||
# aha! svk:merge property changed...
|
||||
sub lookup_svn_merge {
|
||||
my $uuid = shift;
|
||||
my $url = shift;
|
||||
my $merge = shift;
|
||||
|
||||
# We first search for merged tips which are not in our
|
||||
# history. Then, we figure out which git revisions are in
|
||||
# that tip, but not this revision. If all of those revisions
|
||||
# are now marked as merge, we can add the tip as a parent.
|
||||
my @merges = split "\n", $mergeinfo;
|
||||
my @merge_tips;
|
||||
my @merged_commit_ranges;
|
||||
my $url = $self->rewrite_root || $self->{url};
|
||||
for my $merge ( @merges ) {
|
||||
my ($source, $revs) = split ":", $merge;
|
||||
my $path = $source;
|
||||
$path =~ s{^/}{};
|
||||
my $gs = Git::SVN->find_by_url($url.$source, $url, $path);
|
||||
if ( !$gs ) {
|
||||
warn "Couldn't find revmap for $url$source\n";
|
||||
next;
|
||||
return;
|
||||
}
|
||||
my @ranges = split ",", $revs;
|
||||
my ($tip, $tip_commit);
|
||||
my @merged_commit_ranges;
|
||||
# find the tip
|
||||
for my $range ( @ranges ) {
|
||||
my ($bottom, $top) = split "-", $range;
|
||||
$top ||= $bottom;
|
||||
my $bottom_commit =
|
||||
$gs->rev_map_get($bottom, $self->ra_uuid) ||
|
||||
$gs->rev_map_get($bottom+1, $self->ra_uuid);
|
||||
$gs->rev_map_get($bottom, $uuid) ||
|
||||
$gs->rev_map_get($bottom+1, $uuid);
|
||||
my $top_commit;
|
||||
for (; !$top_commit && $top >= $bottom; --$top) {
|
||||
$top_commit =
|
||||
$gs->rev_map_get($top, $self->ra_uuid);
|
||||
$gs->rev_map_get($top, $uuid);
|
||||
}
|
||||
|
||||
unless ($top_commit and $bottom_commit) {
|
||||
|
@ -3046,6 +3038,31 @@ sub find_extra_svn_parents {
|
|||
$tip_commit = $top_commit;
|
||||
}
|
||||
}
|
||||
return ($tip_commit, @merged_commit_ranges);
|
||||
}
|
||||
BEGIN {
|
||||
memoize 'lookup_svn_merge';
|
||||
}
|
||||
|
||||
# note: this function should only be called if the various dirprops
|
||||
# have actually changed
|
||||
sub find_extra_svn_parents {
|
||||
my ($self, $ed, $mergeinfo, $parents) = @_;
|
||||
# aha! svk:merge property changed...
|
||||
|
||||
# We first search for merged tips which are not in our
|
||||
# history. Then, we figure out which git revisions are in
|
||||
# that tip, but not this revision. If all of those revisions
|
||||
# are now marked as merge, we can add the tip as a parent.
|
||||
my @merges = split "\n", $mergeinfo;
|
||||
my @merge_tips;
|
||||
my @merged_commit_ranges;
|
||||
my $url = $self->rewrite_root || $self->{url};
|
||||
my $uuid = $self->ra_uuid;
|
||||
for my $merge ( @merges ) {
|
||||
my ($tip_commit, @ranges) =
|
||||
lookup_svn_merge( $uuid, $url, $merge );
|
||||
push @merged_commit_ranges, @ranges;
|
||||
unless (!$tip_commit or
|
||||
grep { $_ eq $tip_commit } @$parents ) {
|
||||
push @merge_tips, $tip_commit;
|
||||
|
|
Loading…
Reference in New Issue