# [PATCH] Add git-svn branch to allow branch creation in SVN repositories

2 messages from 2008-09-05 to 2008-09-07. Participants: Florian Ragwitz, Eric Wong.
Thread: https://gitlist.dev/t/15381

## Florian Ragwitz, 2008-09-05 11:34

Subject: [PATCH] Add git-svn branch to allow branch creation in SVN repositories
Message-ID: <1220614447-3751-1-git-send-email-rafl@debian.org>
URL: https://gitlist.dev/e/1220614447-3751-1-git-send-email-rafl%40debian.org

```
Signed-off-by: Florian Ragwitz <rafl@debian.org>
---
 Documentation/git-svn.txt |   14 ++++++++++++++
 git-svn.perl              |   30 +++++++++++++++++++++++++++++-
 2 files changed, 43 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 1e644ca..23cf7c3 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -149,6 +149,18 @@ and have no uncommitted changes.
 	is very strongly discouraged.
 --
 
+'branch'::
+    Create a branch in the SVN repository.
+
+-m;;
+--message;;
+    Allows to specify the commit message.
+
+-t;;
+--tag;;
+    Create a tag by using the tags_subdir instead of the branches_subdir
+    specified during git svn init.
+
 'log'::
 	This should make it easy to look up svn log messages when svn
 	users refer to -r/--revision numbers.
@@ -498,6 +510,8 @@ Tracking and contributing to an entire Subversion-managed project
 	git svn clone http://svn.foo.org/project -T trunk -b branches -t tags
 # View all branches and tags you have cloned:
 	git branch -r
+# Create a new branch in SVN
+    git svn branch waldo
 # Reset your master to trunk (or any other branch, replacing 'trunk'
 # with the appropriate name):
 	git reset --hard remotes/trunk
diff --git a/git-svn.perl b/git-svn.perl
index 7a1d26d..55a2052 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -66,7 +66,7 @@ my ($_stdin, $_help, $_edit,
 	$_version, $_fetch_all, $_no_rebase,
 	$_merge, $_strategy, $_dry_run, $_local,
 	$_prefix, $_no_checkout, $_url, $_verbose,
-	$_git_format, $_commit_url);
+	$_git_format, $_commit_url, $_tag);
 $Git::SVN::_follow_parent = 1;
 my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
                     'config-dir=s' => \$Git::SVN::Ra::config_dir,
@@ -131,6 +131,10 @@ my %cmd = (
 			  'revision|r=i' => \$_revision,
 			  'no-rebase' => \$_no_rebase,
 			%cmt_opts, %fc_opts } ],
+	branch => [ \&cmd_branch,
+	            'Create a branch in the SVN repository',
+	            { 'tag|t'       => \$_tag,
+	              'message|m=s' => \$_message } ],
 	'set-tree' => [ \&cmd_set_tree,
 	                "Set an SVN repository to a git tree-ish",
 			{ 'stdin|' => \$_stdin, %cmt_opts, %fc_opts, } ],
@@ -537,6 +541,30 @@ sub cmd_dcommit {
 	unlink $gs->{index};
 }
 
+sub cmd_branch {
+	my $branch_name = shift or die "branch name required\n";
+	my $head        = shift || 'HEAD';
+
+	my ($src, $rev, undef, $gs) = working_head_info($head);
+
+	my $remote      = Git::SVN::read_all_remotes()->{svn};
+	my ($lft, $rgt) = @{ $remote->{ $_tag ? 'tags' : 'branches' }->{path} }{qw/left right/};
+	my $dst         = join '/', $remote->{url}, $lft, $branch_name, ($rgt || ());
+
+	my $ctx = SVN::Client->new(
+		auth    => Git::SVN::Ra::_auth_providers(),
+		log_msg => sub { ${ $_[0] } = $_message || 'Create branch ' . $branch_name },
+	);
+
+	eval {
+		$ctx->ls($dst, 'HEAD', 0);
+	} and die "branch ${branch_name} already exists\n";
+
+	$ctx->copy($src, $rev, $dst);
+
+	$gs->fetch_all;
+}
+
 sub cmd_find_rev {
 	my $revision_or_hash = shift or die "SVN or git revision required ",
 	                                    "as a command-line argument\n";
-- 
1.5.6.5

```

## Eric Wong, 2008-09-07 02:33

Subject: Re: [PATCH] Add git-svn branch to allow branch creation in SVN repositories
Message-ID: <20080907023316.GA12392@untitled>
URL: https://gitlist.dev/e/20080907023316.GA12392%40untitled
In-Reply-To: <1220614447-3751-1-git-send-email-rafl@debian.org>

```
Hi Florian,

Cool.  Some people have been asking for this feature.

I never implemented it myself because I've been unsure if it's
philosophically proper.  Ut's functionally redundant as svn(1) does the
same thing w/o needing a working copy.  But I'll accept your patch with
some minor modifications (comments inline).

Florian Ragwitz <rafl@debian.org> wrote:
> --- a/Documentation/git-svn.txt
> +++ b/Documentation/git-svn.txt
> @@ -149,6 +149,18 @@ and have no uncommitted changes.
>  	is very strongly discouraged.
>  --
>  
> +'branch'::
> +    Create a branch in the SVN repository.

Perhaps a "tag" command that is short for "branch -t" would
be helpful, too.

> +-t;;
> +--tag;;
> +    Create a tag by using the tags_subdir instead of the branches_subdir
> +    specified during git svn init.
> +
> diff --git a/git-svn.perl b/git-svn.perl
> index 7a1d26d..55a2052 100755
> --- a/git-svn.perl
> +++ b/git-svn.perl
> @@ -537,6 +541,30 @@ sub cmd_dcommit {
>  	unlink $gs->{index};
>  }

Coding style things:

1. Don't pad declarations with extra whitespace.
2. No lines over 80 characters (assuming tabs are 8 chars wide)

> +sub cmd_branch {
> +	my $branch_name = shift or die "branch name required\n";
> +	my $head        = shift || 'HEAD';
> +
> +	my ($src, $rev, undef, $gs) = working_head_info($head);
> +
> +	my $remote      = Git::SVN::read_all_remotes()->{svn};

> +	my ($lft, $rgt) = @{ $remote->{ $_tag ? 'tags' : 'branches' }->{path} }{qw/left right/};
> +	my $dst         = join '/', $remote->{url}, $lft, $branch_name, ($rgt || ());

This doesn't appear to fail gracefully for SVN repositories
that don't follow the standard trunk, branches, tags layout.

Can you please ensure that it does and print an error message?

> +
> +	my $ctx = SVN::Client->new(
> +		auth    => Git::SVN::Ra::_auth_providers(),
> +		log_msg => sub { ${ $_[0] } = $_message || 'Create branch ' . $branch_name },
> +	);
> +
> +	eval {
> +		$ctx->ls($dst, 'HEAD', 0);
> +	} and die "branch ${branch_name} already exists\n";

Can you print the URLs being copied and add a --dry-run/-n
option (like dcommit).

> +	$ctx->copy($src, $rev, $dst);
> +
> +	$gs->fetch_all;
> +}
> +
>  sub cmd_find_rev {
>  	my $revision_or_hash = shift or die "SVN or git revision required ",
>  	                                    "as a command-line argument\n";

Can you also add a simple test case so we don't break it in the future?
Thanks.

-- 
Eric Wong

```
