Re: [PATCH] Don't checkout the full tree if avoidable

4 messages, 3 authors, 2016-06-15 · open the first message on its own page

Re: [PATCH] Don't checkout the full tree if avoidable

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:43:37

Steven Walter [off-list ref] writes:
In most cases of branching, the tree is copied unmodified from the trunk
to the branch.  When that is done, we can simply start with the parent's
index and apply the changes on the branch as usual.

Signed-off-by: Steven Walter <redacted>
Eric, do you like this one?
quoted hunk
---
 git-svn.perl |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/git-svn.perl b/git-svn.perl
index 484b057..2ca2042 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1847,6 +1847,13 @@ sub find_parent_branch {
 			$gs->ra->gs_do_switch($r0, $rev, $gs,
 					      $self->full_url, $ed)
 			  or die "SVN connection failed somewhere...\n";
+		} elsif ($self->trees_match($new_url, $r0,
+			                    $self->full_url, $rev)) {
+			$self->tmp_index_do(sub {
+			    command_noisy('read-tree', $parent);
+			});
+			$self->{last_commit} = $parent;
+			# Assume copy with no changes
 		} else {
 			print STDERR "Following parent with do_update\n";
 			$ed = SVN::Git::Fetcher->new($self);
@@ -1859,6 +1866,17 @@ sub find_parent_branch {
 	return undef;
 }
 
+sub trees_match {
+    my ($self, $url1, $rev1, $url2, $rev2) = @_;
+    
+    my $ret=1;
+    open(my $fh, "svn diff $url1\@$rev1 $url2\@$rev2 |");
+    $ret=0 if (<$fh>);
+    close($fh);
+
+    return $ret;
+}
+
 sub do_fetch {
 	my ($self, $paths, $rev) = @_;
 	my $ed;
-- 
1.5.3.1

Re: [PATCH] Don't checkout the full tree if avoidable

From: Eric Wong <hidden>
Date: 2016-06-15 22:43:37

Junio C Hamano [off-list ref] wrote:
Steven Walter [off-list ref] writes:
quoted
In most cases of branching, the tree is copied unmodified from the trunk
to the branch.  When that is done, we can simply start with the parent's
index and apply the changes on the branch as usual.

Signed-off-by: Steven Walter <redacted>
Eric, do you like this one?
Junio, thanks for pinging me about it, I haven't been following the ML
very closely and forgot about this issue.

Steven Walter wrote:
One criticism of the patch: the trees_match function probably needs to
be re-written.  My SVN::Perl-foo is weak.
Yep :)

Steven:

How does the following work for you?  Which version of SVN do you have,
by the way?  I just found a bug with the way SVN::Client::diff() is
exported for SVN 1.1.4, hence the SVN::Pool->new_default_sub usage.

From: Steven Walter <redacted>
Date: Fri, 28 Sep 2007 13:24:19 -0400
Subject: [PATCH] Don't checkout the full tree if avoidable

In most cases of branching, the tree is copied unmodified from the trunk
to the branch.  When that is done, we can simply start with the parent's
index and apply the changes on the branch as usual.

[ew: rewritten from Steven's original to use SVN::Client instead
     of the command-line svn client.

     Since SVN::Client connects separately, we'll share our
     authentication providers array between our usages of
     SVN::Client and SVN::Ra, too.  Bypassing the high-level
     SVN::Client library can avoid this, but the code will be
     much more complex.  Regardless, any implementation of this
     seems to require restarting a connection to the remote
     server.

     Also of note is that SVN 1.4 and later allows a more
     efficient diff_summary to be done instead of a full diff,
     but since this code is only to support SVN < 1.4.4, we'll
     ignore it for now.]

Signed-off-by: Steven Walter <redacted>
Signed-off-by: Eric Wong <redacted>
---
 git-svn.perl |   64 +++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 48 insertions(+), 16 deletions(-)
diff --git a/git-svn.perl b/git-svn.perl
index 484b057..777e436 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1847,6 +1847,16 @@ sub find_parent_branch {
 			$gs->ra->gs_do_switch($r0, $rev, $gs,
 					      $self->full_url, $ed)
 			  or die "SVN connection failed somewhere...\n";
+		} elsif ($self->ra->trees_match($new_url, $r0,
+			                        $self->full_url, $rev)) {
+			print STDERR "Trees match:\n",
+			             "  $new_url\@$r0\n",
+			             "  ${\$self->full_url}\@$rev\n",
+				     "Following parent with no changes\n";
+			$self->tmp_index_do(sub {
+			    command_noisy('read-tree', $parent);
+			});
+			$self->{last_commit} = $parent;
 		} else {
 			print STDERR "Following parent with do_update\n";
 			$ed = SVN::Git::Fetcher->new($self);
@@ -3027,28 +3037,32 @@ BEGIN {
 	}
 }
 
+sub _auth_providers () {
+	[
+	  SVN::Client::get_simple_provider(),
+	  SVN::Client::get_ssl_server_trust_file_provider(),
+	  SVN::Client::get_simple_prompt_provider(
+	    \&Git::SVN::Prompt::simple, 2),
+	  SVN::Client::get_ssl_client_cert_file_provider(),
+	  SVN::Client::get_ssl_client_cert_prompt_provider(
+	    \&Git::SVN::Prompt::ssl_client_cert, 2),
+	  SVN::Client::get_ssl_client_cert_pw_prompt_provider(
+	    \&Git::SVN::Prompt::ssl_client_cert_pw, 2),
+	  SVN::Client::get_username_provider(),
+	  SVN::Client::get_ssl_server_trust_prompt_provider(
+	    \&Git::SVN::Prompt::ssl_server_trust),
+	  SVN::Client::get_username_prompt_provider(
+	    \&Git::SVN::Prompt::username, 2)
+	]
+}
+
 sub new {
 	my ($class, $url) = @_;
 	$url =~ s!/+$!!;
 	return $RA if ($RA && $RA->{url} eq $url);
 
 	SVN::_Core::svn_config_ensure($config_dir, undef);
-	my ($baton, $callbacks) = SVN::Core::auth_open_helper([
-	    SVN::Client::get_simple_provider(),
-	    SVN::Client::get_ssl_server_trust_file_provider(),
-	    SVN::Client::get_simple_prompt_provider(
-	      \&Git::SVN::Prompt::simple, 2),
-	    SVN::Client::get_ssl_client_cert_file_provider(),
-	    SVN::Client::get_ssl_client_cert_prompt_provider(
-	      \&Git::SVN::Prompt::ssl_client_cert, 2),
-	    SVN::Client::get_ssl_client_cert_pw_prompt_provider(
-	      \&Git::SVN::Prompt::ssl_client_cert_pw, 2),
-	    SVN::Client::get_username_provider(),
-	    SVN::Client::get_ssl_server_trust_prompt_provider(
-	      \&Git::SVN::Prompt::ssl_server_trust),
-	    SVN::Client::get_username_prompt_provider(
-	      \&Git::SVN::Prompt::username, 2),
-	  ]);
+	my ($baton, $callbacks) = SVN::Core::auth_open_helper(_auth_providers);
 	my $config = SVN::Core::config_get_config($config_dir);
 	$RA = undef;
 	my $self = SVN::Ra->new(url => $url, auth => $baton,
@@ -3112,6 +3126,24 @@ sub get_log {
 	$ret;
 }
 
+sub trees_match {
+	my ($self, $url1, $rev1, $url2, $rev2) = @_;
+	my $ctx = SVN::Client->new(auth => _auth_providers);
+	my $out = IO::File->new_tmpfile;
+
+	# older SVN (1.1.x) doesn't take $pool as the last parameter for
+	# $ctx->diff(), so we'll create a default one
+	my $pool = SVN::Pool->new_default_sub;
+
+	$ra_invalid = 1; # this will open a new SVN::Ra connection to $url1
+	$ctx->diff([], $url1, $rev1, $url2, $rev2, 1, 1, 0, $out, $out);
+	$out->flush;
+	my $ret = (($out->stat)[7] == 0);
+	close $out or croak $!;
+
+	$ret;
+}
+
 sub get_commit_editor {
 	my ($self, $log, $cb, $pool) = @_;
 	my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef, 0) : ();
-- 
Eric Wong

Re: [PATCH] Don't checkout the full tree if avoidable

From: Steven Walter <hidden>
Date: 2016-06-15 22:43:37

On Mon, Oct 01, 2007 at 04:08:55AM -0700, Eric Wong wrote:
Steven Walter wrote:
quoted
One criticism of the patch: the trees_match function probably needs to
be re-written.  My SVN::Perl-foo is weak.
Yep :)

Steven:

How does the following work for you?  Which version of SVN do you have,
by the way?  I just found a bug with the way SVN::Client::diff() is
exported for SVN 1.1.4, hence the SVN::Pool->new_default_sub usage.
swalter@sentra:~% svn --version
svn, version 1.3.2 (r19776)

This version works great; seems to have exactly the same behavior as my
patch.  Verified that it still falls back to the do_update code when
trees_match fails.
-- 
-Steven Walter [off-list ref]
"A human being should be able to change a diaper, plan an invasion,
butcher a hog, conn a ship, design a building, write a sonnet, balance
accounts, build a wall, set a bone, comfort the dying, take orders,
give orders, cooperate, act alone, solve equations, analyze a new
problem, pitch manure, program a computer, cook a tasty meal, fight
efficiently, die gallantly. Specialization is for insects."
   -Robert Heinlein

Re: [PATCH] Don't checkout the full tree if avoidable

From: Eric Wong <hidden>
Date: 2016-06-15 22:43:38

Steven Walter [off-list ref] wrote:
On Mon, Oct 01, 2007 at 04:08:55AM -0700, Eric Wong wrote:
quoted
Steven Walter wrote:
quoted
One criticism of the patch: the trees_match function probably needs to
be re-written.  My SVN::Perl-foo is weak.
Yep :)

Steven:

How does the following work for you?  Which version of SVN do you have,
by the way?  I just found a bug with the way SVN::Client::diff() is
exported for SVN 1.1.4, hence the SVN::Pool->new_default_sub usage.
swalter@sentra:~% svn --version
svn, version 1.3.2 (r19776)

This version works great; seems to have exactly the same behavior as my
patch.  Verified that it still falls back to the do_update code when
trees_match fails.
Thanks Steven.

Junio: can you please apply my version of Steven's patch?  Thanks.

-- 
Eric Wong
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help