git-svn and branches

Subsystems: the rest

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

git-svn and branches

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

I'm using git-svn to track a rather large subversion repository with a
non-standard layout.  In the past, I've only cared about trunk, but now
I need to occasionally use branches, too.  By adding a second git-svn
remote with the branch URL, I can fetch the branch, and git-svn is even
intelligent enough to notice that the branch was copied off of trunk.

However, git-svn also does a complete checkout for the first revision of
the branch.  By this, I mean it goes through shows "A    file" for every
file in the repository.  This takes quite a while, and seems rather
unnecessary given that git-svn already noticed that the branch shares a
history with trunk, which is already fetched.

Knowing just enough of what git-svn is doing to be dangerous, I whipped
up a short little patch.  This patch seems to work for the common case,
and avoids fetching every file from subversion.  It does break
sometimes, however, and I don't understand why.

Maybe someone with a better grasps of the code can see what I did wrong,
or suggest a better means to my end?
diff --git a/git-svn.perl b/git-svn.perl
index 484b057..1bc92b6 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1848,9 +1848,10 @@ sub find_parent_branch {
                                              $self->full_url, $ed)
                          or die "SVN connection failed somewhere...\n";
                } else {
+                       $self->assert_index_clean($parent);
                        print STDERR "Following parent with do_update\n";
                        $ed = SVN::Git::Fetcher->new($self);
-                       $self->ra->gs_do_update($rev, $rev, $self, $ed)
+                       $self->ra->gs_do_update($rev, $r0, $self, $ed)
                          or die "SVN connection failed somewhere...\n";
                }
                print STDERR "Successfully followed parent\n";
-- 
-Steven Walter <stevenrwalter@gmail.com>
"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: git-svn and branches

From: Sam Vilain <hidden>
Date: 2016-06-15 22:43:36

Steven Walter wrote:
Knowing just enough of what git-svn is doing to be dangerous, I
whipped up a short little patch.  This patch seems to work for the
common case, and avoids fetching every file from subversion.  It does
break sometimes, however, and I don't understand why.

Maybe someone with a better grasps of the code can see what I did
wrong, or suggest a better means to my end?
Try also with the SVN trunk - the do_switch API has recently been added
and it also avoids this excess checkout.  I'm not sure why a solution
like you post isn't used, perhaps Eric can comment further.

Sam.
quoted hunk
diff --git a/git-svn.perl b/git-svn.perl
index 484b057..1bc92b6 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1848,9 +1848,10 @@ sub find_parent_branch {
                                              $self->full_url, $ed)
                          or die "SVN connection failed somewhere...\n";
                } else {
+                       $self->assert_index_clean($parent);
                        print STDERR "Following parent with do_update\n";
                        $ed = SVN::Git::Fetcher->new($self);
-                       $self->ra->gs_do_update($rev, $rev, $self, $ed)
+                       $self->ra->gs_do_update($rev, $r0, $self, $ed)
                          or die "SVN connection failed somewhere...\n";
                }
                print STDERR "Successfully followed parent\n";

Re: git-svn and branches

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

Steven Walter [off-list ref] wrote:
I'm using git-svn to track a rather large subversion repository with a
non-standard layout.  In the past, I've only cared about trunk, but now
I need to occasionally use branches, too.  By adding a second git-svn
remote with the branch URL, I can fetch the branch, and git-svn is even
intelligent enough to notice that the branch was copied off of trunk.

However, git-svn also does a complete checkout for the first revision of
the branch.  By this, I mean it goes through shows "A    file" for every
file in the repository.  This takes quite a while, and seems rather
unnecessary given that git-svn already noticed that the branch shares a
history with trunk, which is already fetched.

Knowing just enough of what git-svn is doing to be dangerous, I whipped
up a short little patch.  This patch seems to work for the common case,
and avoids fetching every file from subversion.  It does break
sometimes, however, and I don't understand why.

Maybe someone with a better grasps of the code can see what I did wrong,
or suggest a better means to my end?
I believe your case handles where a branch is created directly from a
trunk copy with no file modifications in the branch, but not when a
branch is created and files are modified in the trunk (or branch) within
the same revision.  Is this what's happening?

Additionally, I think this breaks when an entire trunk or branch is
moved around because the original directory has moved or gone away:

  /trunk => /project-a/trunk

Anyways, as Sam said, newer SVN (1.4.4+) has a working do_switch()
function and that code path will never be hit at all.
quoted hunk
diff --git a/git-svn.perl b/git-svn.perl
index 484b057..1bc92b6 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1848,9 +1848,10 @@ sub find_parent_branch {
                                              $self->full_url, $ed)
                          or die "SVN connection failed somewhere...\n";
                } else {
+                       $self->assert_index_clean($parent);
                        print STDERR "Following parent with do_update\n";
                        $ed = SVN::Git::Fetcher->new($self);
-                       $self->ra->gs_do_update($rev, $rev, $self, $ed)
+                       $self->ra->gs_do_update($rev, $r0, $self, $ed)
                          or die "SVN connection failed somewhere...\n";
                }
                print STDERR "Successfully followed parent\n";
-- 
Eric Wong

Re: git-svn and branches

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

On Thu, Sep 27, 2007 at 12:24:04AM -0700, Eric Wong wrote:
I believe your case handles where a branch is created directly from a
trunk copy with no file modifications in the branch, but not when a
branch is created and files are modified in the trunk (or branch) within
the same revision.  Is this what's happening?

Additionally, I think this breaks when an entire trunk or branch is
moved around because the original directory has moved or gone away:

  /trunk => /project-a/trunk

Anyways, as Sam said, newer SVN (1.4.4+) has a working do_switch()
function and that code path will never be hit at all.
I think you're right that my code would only handle a verbatim copy.  I
made a few changes and I think I have something that is more generally
useful.  Using a newer version of subversion isn't practical for me, as
this is a work situation where I don't have control of the workstations.

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

Patch to follow
-- 
-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

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

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

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>
---
 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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help