git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sam Vilain <sam@vilain.net>
To: git@vger.kernel.org
Cc: Eric Wong <normalperson@yhbt.net>,
	Andrew Myrick <amyrick@gmail.com>, Sam Vilain <sam@vilain.net>
Subject: [PATCH 4/5] git-svn: exclude already merged tips using one rev-list call
Date: Sun, 20 Dec 2009 05:33:54 +1300	[thread overview]
Message-ID: <1261240435-8948-5-git-send-email-sam@vilain.net> (raw)
In-Reply-To: <1261240435-8948-4-git-send-email-sam@vilain.net>

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>
---
 git-svn.perl |   52 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index 9cf4a3e..7a790d7 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -3011,6 +3011,41 @@ BEGIN {
 	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
 # have actually changed
 sub find_extra_svn_parents {
@@ -3023,23 +3058,32 @@ sub find_extra_svn_parents {
 	# 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;
+	my %ranges;
 	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;
+			$ranges{$tip_commit} = \@ranges;
 		} else {
 			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 ) {
 		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,
 			   "--not", @$parents );
 		my ($msg_fh, $ctx) = command_output_pipe(@cmd);
@@ -3049,7 +3093,7 @@ sub find_extra_svn_parents {
 		}
 		command_close_pipe($msg_fh, $ctx);
 		if ( $new ) {
-			push @cmd, @merged_commit_ranges;
+			push @cmd, @$ranges;
 			my ($msg_fh, $ctx) = command_output_pipe(@cmd);
 			my $unmerged;
 			while ( <$msg_fh> ) {
-- 
1.6.3.3

  reply	other threads:[~2009-12-19 16:34 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-19 16:33 Efficiency and correctness patches for git-svn mergeinfo support Sam Vilain
2009-12-19 16:33 ` [PATCH 1/5] git-svn: expand the svn mergeinfo test suite, highlighting some failures Sam Vilain
2009-12-19 16:33   ` [PATCH 2/5] git-svn: memoize conversion of SVN merge ticket info to git commit ranges Sam Vilain
2009-12-19 16:33     ` [PATCH 3/5] git-svn: fix some mistakes with interpreting SVN mergeinfo " Sam Vilain
2009-12-19 16:33       ` Sam Vilain [this message]
2009-12-19 16:33         ` [PATCH 5/5] git-svn: detect cherry-picks correctly Sam Vilain
2009-12-19 16:37     ` [PATCH 2/5] git-svn: memoize conversion of SVN merge ticket info to git commit ranges Sam Vilain
2009-12-20 21:24     ` Sam Vilain
2009-12-21 10:44       ` Eric Wong
2009-12-19 16:42 ` Efficiency and correctness patches for git-svn mergeinfo support Sam Vilain
2009-12-19 22:15 ` Andrew Myrick
2009-12-20 21:07   ` Sam Vilain
2009-12-20 22:03     ` Andrew Myrick

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1261240435-8948-5-git-send-email-sam@vilain.net \
    --to=sam@vilain.net \
    --cc=amyrick@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=normalperson@yhbt.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).