git-svn: exclude already merged tips using one rev-list call
The old function would have to check all mentioned merge tips, every time that the mergeinfo ticket changed. This involved 1-2 rev-list operation for each listed mergeinfo line. If there are a lot of feature branches being merged into a trunk, this makes for a very expensive operation for detecting the new parents on every merge. This new version first uses a single 'rev-list' to figure out which commit ranges are already reachable from the parents. This is used to eliminate the already merged branches from the list. Signed-off-by: Sam Vilain <sam@vilain.net> Acked-by: Eric Wong <normalperson@yhbt.net>
This commit is contained in:
parent
33973a5b17
commit
ea020cbd6a
52
git-svn.perl
52
git-svn.perl
@ -3038,6 +3038,41 @@ BEGIN {
|
|||||||
memoize 'lookup_svn_merge';
|
memoize 'lookup_svn_merge';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub parents_exclude {
|
||||||
|
my $parents = shift;
|
||||||
|
my @commits = @_;
|
||||||
|
return unless @commits;
|
||||||
|
|
||||||
|
my @excluded;
|
||||||
|
my $excluded;
|
||||||
|
do {
|
||||||
|
my @cmd = ('rev-list', "-1", @commits, "--not", @$parents );
|
||||||
|
$excluded = command_oneline(@cmd);
|
||||||
|
if ( $excluded ) {
|
||||||
|
my @new;
|
||||||
|
my $found;
|
||||||
|
for my $commit ( @commits ) {
|
||||||
|
if ( $commit eq $excluded ) {
|
||||||
|
push @excluded, $commit;
|
||||||
|
$found++;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
push @new, $commit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
die "saw commit '$excluded' in rev-list output, "
|
||||||
|
."but we didn't ask for that commit (wanted: @commits --not @$parents)"
|
||||||
|
unless $found;
|
||||||
|
@commits = @new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ($excluded and @commits);
|
||||||
|
|
||||||
|
return @excluded;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# note: this function should only be called if the various dirprops
|
# note: this function should only be called if the various dirprops
|
||||||
# have actually changed
|
# have actually changed
|
||||||
sub find_extra_svn_parents {
|
sub find_extra_svn_parents {
|
||||||
@ -3050,23 +3085,32 @@ sub find_extra_svn_parents {
|
|||||||
# are now marked as merge, we can add the tip as a parent.
|
# are now marked as merge, we can add the tip as a parent.
|
||||||
my @merges = split "\n", $mergeinfo;
|
my @merges = split "\n", $mergeinfo;
|
||||||
my @merge_tips;
|
my @merge_tips;
|
||||||
my @merged_commit_ranges;
|
|
||||||
my $url = $self->rewrite_root || $self->{url};
|
my $url = $self->rewrite_root || $self->{url};
|
||||||
my $uuid = $self->ra_uuid;
|
my $uuid = $self->ra_uuid;
|
||||||
|
my %ranges;
|
||||||
for my $merge ( @merges ) {
|
for my $merge ( @merges ) {
|
||||||
my ($tip_commit, @ranges) =
|
my ($tip_commit, @ranges) =
|
||||||
lookup_svn_merge( $uuid, $url, $merge );
|
lookup_svn_merge( $uuid, $url, $merge );
|
||||||
push @merged_commit_ranges, @ranges;
|
|
||||||
unless (!$tip_commit or
|
unless (!$tip_commit or
|
||||||
grep { $_ eq $tip_commit } @$parents ) {
|
grep { $_ eq $tip_commit } @$parents ) {
|
||||||
push @merge_tips, $tip_commit;
|
push @merge_tips, $tip_commit;
|
||||||
|
$ranges{$tip_commit} = \@ranges;
|
||||||
} else {
|
} else {
|
||||||
push @merge_tips, undef;
|
push @merge_tips, undef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my %excluded = map { $_ => 1 }
|
||||||
|
parents_exclude($parents, grep { defined } @merge_tips);
|
||||||
|
|
||||||
|
# check merge tips for new parents
|
||||||
|
my @new_parents;
|
||||||
for my $merge_tip ( @merge_tips ) {
|
for my $merge_tip ( @merge_tips ) {
|
||||||
my $spec = shift @merges;
|
my $spec = shift @merges;
|
||||||
next unless $merge_tip;
|
next unless $merge_tip and $excluded{$merge_tip};
|
||||||
|
|
||||||
|
my $ranges = $ranges{$merge_tip};
|
||||||
|
|
||||||
my @cmd = ('rev-list', "-1", $merge_tip,
|
my @cmd = ('rev-list', "-1", $merge_tip,
|
||||||
"--not", @$parents );
|
"--not", @$parents );
|
||||||
my ($msg_fh, $ctx) = command_output_pipe(@cmd);
|
my ($msg_fh, $ctx) = command_output_pipe(@cmd);
|
||||||
@ -3076,7 +3120,7 @@ sub find_extra_svn_parents {
|
|||||||
}
|
}
|
||||||
command_close_pipe($msg_fh, $ctx);
|
command_close_pipe($msg_fh, $ctx);
|
||||||
if ( $new ) {
|
if ( $new ) {
|
||||||
push @cmd, @merged_commit_ranges;
|
push @cmd, @$ranges;
|
||||||
my ($msg_fh, $ctx) = command_output_pipe(@cmd);
|
my ($msg_fh, $ctx) = command_output_pipe(@cmd);
|
||||||
my $unmerged;
|
my $unmerged;
|
||||||
while ( <$msg_fh> ) {
|
while ( <$msg_fh> ) {
|
||||||
|
Loading…
Reference in New Issue
Block a user