Skip to content

Commit 52a7311

Browse files
committed
Merge branch 'dm/svn-branch'
* dm/svn-branch: Add git-svn branch to allow branch creation in SVN repositories
2 parents bc36540 + 5de70ef commit 52a7311

File tree

3 files changed

+128
-2
lines changed

3 files changed

+128
-2
lines changed

Documentation/git-svn.txt

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,22 @@ and have no uncommitted changes.
149149
is very strongly discouraged.
150150
--
151151

152+
'branch'::
153+
Create a branch in the SVN repository.
154+
155+
-m;;
156+
--message;;
157+
Allows to specify the commit message.
158+
159+
-t;;
160+
--tag;;
161+
Create a tag by using the tags_subdir instead of the branches_subdir
162+
specified during git svn init.
163+
164+
'tag'::
165+
Create a tag in the SVN repository. This is a shorthand for
166+
'branch -t'.
167+
152168
'log'::
153169
This should make it easy to look up svn log messages when svn
154170
users refer to -r/--revision numbers.
@@ -372,7 +388,8 @@ Passed directly to 'git-rebase' when using 'dcommit' if a
372388
-n::
373389
--dry-run::
374390

375-
This can be used with the 'dcommit' and 'rebase' commands.
391+
This can be used with the 'dcommit', 'rebase', 'branch' and 'tag'
392+
commands.
376393

377394
For 'dcommit', print out the series of git arguments that would show
378395
which diffs would be committed to SVN.
@@ -381,6 +398,9 @@ For 'rebase', display the local branch associated with the upstream svn
381398
repository associated with the current branch and the URL of svn
382399
repository that will be fetched from.
383400

401+
For 'branch' and 'tag', display the urls that will be used for copying when
402+
creating the branch or tag.
403+
384404
--
385405

386406
ADVANCED OPTIONS
@@ -498,6 +518,8 @@ Tracking and contributing to an entire Subversion-managed project
498518
git svn clone http://svn.example.com/project -T trunk -b branches -t tags
499519
# View all branches and tags you have cloned:
500520
git branch -r
521+
# Create a new branch in SVN
522+
git svn branch waldo
501523
# Reset your master to trunk (or any other branch, replacing 'trunk'
502524
# with the appropriate name):
503525
git reset --hard remotes/trunk

git-svn.perl

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ BEGIN
6666
$_version, $_fetch_all, $_no_rebase,
6767
$_merge, $_strategy, $_dry_run, $_local,
6868
$_prefix, $_no_checkout, $_url, $_verbose,
69-
$_git_format, $_commit_url);
69+
$_git_format, $_commit_url, $_tag);
7070
$Git::SVN::_follow_parent = 1;
7171
my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
7272
'config-dir=s' => \$Git::SVN::Ra::config_dir,
@@ -131,6 +131,15 @@ BEGIN
131131
'revision|r=i' => \$_revision,
132132
'no-rebase' => \$_no_rebase,
133133
%cmt_opts, %fc_opts } ],
134+
branch => [ \&cmd_branch,
135+
'Create a branch in the SVN repository',
136+
{ 'message|m=s' => \$_message,
137+
'dry-run|n' => \$_dry_run,
138+
'tag|t' => \$_tag } ],
139+
tag => [ sub { $_tag = 1; cmd_branch(@_) },
140+
'Create a tag in the SVN repository',
141+
{ 'message|m=s' => \$_message,
142+
'dry-run|n' => \$_dry_run } ],
134143
'set-tree' => [ \&cmd_set_tree,
135144
"Set an SVN repository to a git tree-ish",
136145
{ 'stdin|' => \$_stdin, %cmt_opts, %fc_opts, } ],
@@ -537,6 +546,42 @@ sub cmd_dcommit {
537546
unlink $gs->{index};
538547
}
539548

549+
sub cmd_branch {
550+
my ($branch_name, $head) = @_;
551+
552+
unless (defined $branch_name && length $branch_name) {
553+
die(($_tag ? "tag" : "branch") . " name required\n");
554+
}
555+
$head ||= 'HEAD';
556+
557+
my ($src, $rev, undef, $gs) = working_head_info($head);
558+
559+
my $remote = Git::SVN::read_all_remotes()->{svn};
560+
my $glob = $remote->{ $_tag ? 'tags' : 'branches' };
561+
my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/};
562+
my $dst = join '/', $remote->{url}, $lft, $branch_name, ($rgt || ());
563+
564+
my $ctx = SVN::Client->new(
565+
auth => Git::SVN::Ra::_auth_providers(),
566+
log_msg => sub {
567+
${ $_[0] } = defined $_message
568+
? $_message
569+
: 'Create ' . ($_tag ? 'tag ' : 'branch ' )
570+
. $branch_name;
571+
},
572+
);
573+
574+
eval {
575+
$ctx->ls($dst, 'HEAD', 0);
576+
} and die "branch ${branch_name} already exists\n";
577+
578+
print "Copying ${src} at r${rev} to ${dst}...\n";
579+
$ctx->copy($src, $rev, $dst)
580+
unless $_dry_run;
581+
582+
$gs->fetch_all;
583+
}
584+
540585
sub cmd_find_rev {
541586
my $revision_or_hash = shift or die "SVN or git revision required ",
542587
"as a command-line argument\n";

t/t9128-git-svn-cmd-branch.sh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2008 Deskin Miller
4+
#
5+
6+
test_description='git svn partial-rebuild tests'
7+
. ./lib-git-svn.sh
8+
9+
test_expect_success 'initialize svnrepo' '
10+
mkdir import &&
11+
(
12+
cd import &&
13+
mkdir trunk branches tags &&
14+
cd trunk &&
15+
echo foo > foo &&
16+
cd .. &&
17+
svn import -m "import for git-svn" . "$svnrepo" >/dev/null &&
18+
cd .. &&
19+
rm -rf import &&
20+
svn co "$svnrepo"/trunk trunk &&
21+
cd trunk &&
22+
echo bar >> foo &&
23+
svn ci -m "updated trunk" &&
24+
cd .. &&
25+
rm -rf trunk
26+
)
27+
'
28+
29+
test_expect_success 'import into git' '
30+
git svn init --stdlayout "$svnrepo" &&
31+
git svn fetch &&
32+
git checkout remotes/trunk
33+
'
34+
35+
test_expect_success 'git svn branch tests' '
36+
git svn branch a &&
37+
base=$(git rev-parse HEAD:) &&
38+
test $base = $(git rev-parse remotes/a:) &&
39+
git svn branch -m "created branch b blah" b &&
40+
test $base = $(git rev-parse remotes/b:) &&
41+
test_must_fail git branch -m "no branchname" &&
42+
git svn branch -n c &&
43+
test_must_fail git rev-parse remotes/c &&
44+
test_must_fail git svn branch a &&
45+
git svn branch -t tag1 &&
46+
test $base = $(git rev-parse remotes/tags/tag1:) &&
47+
git svn branch --tag tag2 &&
48+
test $base = $(git rev-parse remotes/tags/tag2:) &&
49+
git svn tag tag3 &&
50+
test $base = $(git rev-parse remotes/tags/tag3:) &&
51+
git svn tag -m "created tag4 foo" tag4 &&
52+
test $base = $(git rev-parse remotes/tags/tag4:) &&
53+
test_must_fail git svn tag -m "no tagname" &&
54+
git svn tag -n tag5 &&
55+
test_must_fail git rev-parse remotes/tags/tag5 &&
56+
test_must_fail git svn tag tag1
57+
'
58+
59+
test_done

0 commit comments

Comments
 (0)