Skip to content

Commit ea020cb

Browse files
samvEric Wong
authored andcommitted
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 <[email protected]> Acked-by: Eric Wong <[email protected]>
1 parent 33973a5 commit ea020cb

File tree

1 file changed

+48
-4
lines changed

1 file changed

+48
-4
lines changed

git-svn.perl

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3038,6 +3038,41 @@ BEGIN
30383038
memoize 'lookup_svn_merge';
30393039
}
30403040

3041+
sub parents_exclude {
3042+
my $parents = shift;
3043+
my @commits = @_;
3044+
return unless @commits;
3045+
3046+
my @excluded;
3047+
my $excluded;
3048+
do {
3049+
my @cmd = ('rev-list', "-1", @commits, "--not", @$parents );
3050+
$excluded = command_oneline(@cmd);
3051+
if ( $excluded ) {
3052+
my @new;
3053+
my $found;
3054+
for my $commit ( @commits ) {
3055+
if ( $commit eq $excluded ) {
3056+
push @excluded, $commit;
3057+
$found++;
3058+
last;
3059+
}
3060+
else {
3061+
push @new, $commit;
3062+
}
3063+
}
3064+
die "saw commit '$excluded' in rev-list output, "
3065+
."but we didn't ask for that commit (wanted: @commits --not @$parents)"
3066+
unless $found;
3067+
@commits = @new;
3068+
}
3069+
}
3070+
while ($excluded and @commits);
3071+
3072+
return @excluded;
3073+
}
3074+
3075+
30413076
# note: this function should only be called if the various dirprops
30423077
# have actually changed
30433078
sub find_extra_svn_parents {
@@ -3050,23 +3085,32 @@ sub find_extra_svn_parents {
30503085
# are now marked as merge, we can add the tip as a parent.
30513086
my @merges = split "\n", $mergeinfo;
30523087
my @merge_tips;
3053-
my @merged_commit_ranges;
30543088
my $url = $self->rewrite_root || $self->{url};
30553089
my $uuid = $self->ra_uuid;
3090+
my %ranges;
30563091
for my $merge ( @merges ) {
30573092
my ($tip_commit, @ranges) =
30583093
lookup_svn_merge( $uuid, $url, $merge );
3059-
push @merged_commit_ranges, @ranges;
30603094
unless (!$tip_commit or
30613095
grep { $_ eq $tip_commit } @$parents ) {
30623096
push @merge_tips, $tip_commit;
3097+
$ranges{$tip_commit} = \@ranges;
30633098
} else {
30643099
push @merge_tips, undef;
30653100
}
30663101
}
3102+
3103+
my %excluded = map { $_ => 1 }
3104+
parents_exclude($parents, grep { defined } @merge_tips);
3105+
3106+
# check merge tips for new parents
3107+
my @new_parents;
30673108
for my $merge_tip ( @merge_tips ) {
30683109
my $spec = shift @merges;
3069-
next unless $merge_tip;
3110+
next unless $merge_tip and $excluded{$merge_tip};
3111+
3112+
my $ranges = $ranges{$merge_tip};
3113+
30703114
my @cmd = ('rev-list', "-1", $merge_tip,
30713115
"--not", @$parents );
30723116
my ($msg_fh, $ctx) = command_output_pipe(@cmd);
@@ -3076,7 +3120,7 @@ sub find_extra_svn_parents {
30763120
}
30773121
command_close_pipe($msg_fh, $ctx);
30783122
if ( $new ) {
3079-
push @cmd, @merged_commit_ranges;
3123+
push @cmd, @$ranges;
30803124
my ($msg_fh, $ctx) = command_output_pipe(@cmd);
30813125
my $unmerged;
30823126
while ( <$msg_fh> ) {

0 commit comments

Comments
 (0)