Commits

Junio C Hamano  committed 2bd6dbb Merge

Merge git://git.bogomips.org/git-svn

* git://git.bogomips.org/git-svn:
git-svn: allow subset of branches/tags to be specified in glob spec
git-svn: allow UUID to be manually remapped via rewriteUUID
git-svn: update svn mergeinfo test suite
git-svn: document --username/commit-url for branch/tag
git-svn: add --username/commit-url options for branch/tag
git-svn: respect commiturl option for branch/tag
git-svn: fix mismatched src/dst errors for branch/tag
git-svn: handle merge-base failures
git-svn: ignore changeless commits when checking for a cherry-pick

  • Participants
  • Parent commits a88183f, 0757620

Comments (0)

Files changed (9)

File Documentation/git-svn.txt

 	Set the 'useSvnsyncProps' option in the [svn-remote] config.
 --rewrite-root=<URL>;;
 	Set the 'rewriteRoot' option in the [svn-remote] config.
+--rewrite-uuid=<UUID>;;
+	Set the 'rewriteUUID' option in the [svn-remote] config.
 --username=<USER>;;
 	For transports that SVN handles authentication for (http,
 	https, and plain svn), specify the username.  For other
 where <name> is the name of the SVN repository as specified by the -R option to
 'init' (or "svn" by default).
 
+--username;;
+	Specify the SVN username to perform the commit as.  This option overrides
+	configuration property 'username'.
+
+--commit-url;;
+	Use the specified URL to connect to the destination Subversion
+	repository.  This is useful in cases where the source SVN
+	repository is read-only.  This option overrides configuration
+	property 'commiturl'.
++
+	git config --get-all svn-remote.<name>.commiturl
++
+
 'tag'::
 	Create a tag in the SVN repository. This is a shorthand for
 	'branch -t'.
 	the repository with a public http:// or svn:// URL in the
 	metadata so users of it will see the public URL.
 
+svn-remote.<name>.rewriteUUID::
+	Similar to the useSvmProps option; this is for users who need
+	to remap the UUID manually. This may be useful in situations
+	where the original UUID is not available via either useSvmProps
+	or useSvnsyncProps.
+
 svn.brokenSymlinkWorkaround::
 	This disables potentially expensive checks to workaround
 	broken symlinks checked into SVN by broken clients.  Set this
 	revision fetched.  If unset, 'git svn' assumes this option to
 	be "true".
 
-Since the noMetadata, rewriteRoot, useSvnsyncProps and useSvmProps
+Since the noMetadata, rewriteRoot, rewriteUUID, useSvnsyncProps and useSvmProps
 options all affect the metadata generated and used by 'git svn'; they
 *must* be set in the configuration file before any history is imported
 and these settings should never be changed once they are set.
 
-Additionally, only one of these four options can be used per-svn-remote
-section because they affect the 'git-svn-id:' metadata line.
+Additionally, only one of these options can be used per svn-remote
+section because they affect the 'git-svn-id:' metadata line, except
+for rewriteRoot and rewriteUUID which can be used together.
 
 
 BASIC EXAMPLES
 type of configuration is not automatically created by 'init' and
 should be manually entered with a text-editor or using 'git config'.
 
+It is also possible to fetch a subset of branches or tags by using a
+comma-separated list of names within braces. For example:
+
+------------------------------------------------------------------------
+[svn-remote "huge-project"]
+	url = http://server.org/svn
+	fetch = trunk/src:refs/remotes/trunk
+	branches = branches/{red,green}/src:refs/remotes/branches/*
+	tags = tags/{1.0,2.0}/src:refs/remotes/tags/*
+------------------------------------------------------------------------
+
+Note that git-svn keeps track of the highest revision in which a branch
+or tag has appeared. If the subset of branches or tags is changed after
+fetching, then .git/svn/.metadata must be manually edited to remove (or
+reset) branches-maxRev and/or tags-maxRev as appropriate.
+
 SEE ALSO
 --------
 linkgit:git-rebase[1]

File git-svn.perl

 		  'use-svm-props' => sub { $icv{useSvmProps} = 1 },
 		  'use-svnsync-props' => sub { $icv{useSvnsyncProps} = 1 },
 		  'rewrite-root=s' => sub { $icv{rewriteRoot} = $_[1] },
+		  'rewrite-uuid=s' => sub { $icv{rewriteUUID} = $_[1] },
                   %remote_opts );
 my %cmt_opts = ( 'edit|e' => \$_edit,
 		'rmdir' => \$SVN::Git::Editor::_rmdir,
 	            { 'message|m=s' => \$_message,
 	              'destination|d=s' => \$_branch_dest,
 	              'dry-run|n' => \$_dry_run,
-		      'tag|t' => \$_tag } ],
+	              'tag|t' => \$_tag,
+	              'username=s' => \$Git::SVN::Prompt::_username,
+	              'commit-url=s' => \$_commit_url } ],
 	tag => [ sub { $_tag = 1; cmd_branch(@_) },
 	         'Create a tag in the SVN repository',
 	         { 'message|m=s' => \$_message,
 	           'destination|d=s' => \$_branch_dest,
-	           'dry-run|n' => \$_dry_run } ],
+	           'dry-run|n' => \$_dry_run,
+	           'username=s' => \$Git::SVN::Prompt::_username,
+	           'commit-url=s' => \$_commit_url } ],
 	'set-tree' => [ \&cmd_set_tree,
 	                "Set an SVN repository to a git tree-ish",
 			{ 'stdin' => \$_stdin, %cmt_opts, %fc_opts, } ],
 		}
 	}
 	my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/};
-	my $dst = join '/', $remote->{url}, $lft, $branch_name, ($rgt || ());
+	my $url;
+	if (defined $_commit_url) {
+		$url = $_commit_url;
+	} else {
+		$url = eval { command_oneline('config', '--get',
+			"svn-remote.$gs->{repo_id}.commiturl") };
+		if (!$url) {
+			$url = $remote->{url};
+		}
+	}
+	my $dst = join '/', $url, $lft, $branch_name, ($rgt || ());
+
+	if ($dst =~ /^https:/ && $src =~ /^http:/) {
+		$src=~s/^http:/https:/;
+	}
 
 	my $ctx = SVN::Client->new(
 		auth    => Git::SVN::Ra::_auth_providers(),
 			my $rs = {
 			    t => $t,
 			    remote => $remote,
-			    path => Git::SVN::GlobSpec->new($local_ref),
-			    ref => Git::SVN::GlobSpec->new($remote_ref) };
+			    path => Git::SVN::GlobSpec->new($local_ref, 1),
+			    ref => Git::SVN::GlobSpec->new($remote_ref, 0) };
 			if (length($rs->{ref}->{right}) != 0) {
 				die "The '*' glob character must be the last ",
 				    "character of '$remote_ref'\n";
 		die "Can't have both 'useSvnsyncProps' and 'rewriteRoot' ",
 		    "options set!\n";
 	}
+	if ($self->rewrite_uuid) {
+		die "Can't have both 'useSvnsyncProps' and 'rewriteUUID' ",
+		    "options set!\n";
+	}
 
 	my $svnsync;
 	# see if we have it in our config, first:
 	$self->{-rewrite_root} = $rwr;
 }
 
+sub rewrite_uuid {
+	my ($self) = @_;
+	return $self->{-rewrite_uuid} if exists $self->{-rewrite_uuid};
+	my $k = "svn-remote.$self->{repo_id}.rewriteUUID";
+	my $rwid = eval { command_oneline(qw/config --get/, $k) };
+	if ($rwid) {
+		$rwid =~ s#/+$##;
+		if ($rwid !~ m#^[a-f0-9]{8}-(?:[a-f0-9]{4}-){3}[a-f0-9]{12}$#) {
+			die "$rwid is not a valid UUID (key: $k)\n";
+		}
+	}
+	$self->{-rewrite_uuid} = $rwid;
+}
+
 sub metadata_url {
 	my ($self) = @_;
 	($self->rewrite_root || $self->{url}) .
 	for my $range ( @ranges ) {
 		delete @commits{_rev_list($range)};
 	}
+	for my $commit (keys %commits) {
+		if (has_no_changes($commit)) {
+			delete $commits{$commit};
+		}
+	}
 	return (keys %commits);
 }
 
+sub has_no_changes {
+	my $commit = shift;
+
+	my @revs = split / /, command_oneline(
+		qw(rev-list --parents -1 -m), $commit);
+
+	# Commits with no parents, e.g. the start of a partial branch,
+	# have changes by definition.
+	return 1 if (@revs < 2);
+
+	# Commits with multiple parents, e.g a merge, have no changes
+	# by definition.
+	return 0 if (@revs > 2);
+
+	return (command_oneline("rev-parse", "$commit^{tree}") eq
+		command_oneline("rev-parse", "$commit~1^{tree}"));
+}
+
 BEGIN {
 	memoize 'lookup_svn_merge';
 	memoize 'check_cherry_pick';
+	memoize 'has_no_changes';
 }
 
 sub parents_exclude {
 		my $ranges = $ranges{$merge_tip};
 
 		# check out 'new' tips
-		my $merge_base = command_oneline(
-			"merge-base",
-			@$parents, $merge_tip,
-		       );
+		my $merge_base;
+		eval {
+			$merge_base = command_oneline(
+				"merge-base",
+				@$parents, $merge_tip,
+			);
+		};
+		if ($@) {
+			die "An error occurred during merge-base"
+				unless $@->isa("Git::Error::Command");
+
+			warn "W: Cannot find common ancestor between ".
+			     "@$parents and $merge_tip. Ignoring merge info.\n";
+			next;
+		}
 
 		# double check that there are no missing non-merge commits
 		my (@incomplete) = check_cherry_pick(
 			die "Can't have both 'useSvmProps' and 'rewriteRoot' ",
 			    "options set!\n";
 		}
+		if ($self->rewrite_uuid) {
+			die "Can't have both 'useSvmProps' and 'rewriteUUID' ",
+			    "options set!\n";
+		}
 		my ($uuid, $r) = $headrev =~ m{^([a-f\d\-]{30,}):(\d+)$}i;
 		# we don't want "SVM: initializing mirror for junk" ...
 		return undef if $r == 0;
 	} else {
 		my $url = $self->metadata_url;
 		remove_username($url);
-		$log_entry{metadata} = "$url\@$rev " .
-		                       $self->ra->get_uuid;
-		$email ||= "$author\@" . $self->ra->get_uuid;
-		$commit_email ||= "$author\@" . $self->ra->get_uuid;
+		my $uuid = $self->rewrite_uuid || $self->ra->get_uuid;
+		$log_entry{metadata} = "$url\@$rev " . $uuid;
+		$email ||= "$author\@" . $uuid;
+		$commit_email ||= "$author\@" . $uuid;
 	}
 	$log_entry{name} = $name;
 	$log_entry{email} = $email;
 				'--');
 	my $metadata_url = $self->metadata_url;
 	remove_username($metadata_url);
-	my $svn_uuid = $self->ra_uuid;
+	my $svn_uuid = $self->rewrite_uuid || $self->ra_uuid;
 	my $c;
 	while (<$log>) {
 		if ( m{^commit ($::sha1)$} ) {
 			next if (length $g->{path}->{right} &&
 				 ($self->check_path($p, $r) !=
 				  $SVN::Node::dir));
+			next unless $p =~ /$g->{path}->{regex}/;
 			$exists->{$p} = Git::SVN->init($self->{url}, $p, undef,
 					 $g->{ref}->full_path($de), 1);
 		}
 use warnings;
 
 sub new {
-	my ($class, $glob) = @_;
+	my ($class, $glob, $pattern_ok) = @_;
 	my $re = $glob;
 	$re =~ s!/+$!!g; # no need for trailing slashes
-	$re =~ m!^([^*]*)(\*(?:/\*)*)(.*)$!;
-	my $temp = $re;
-	my ($left, $right) = ($1, $3);
-	$re = $2;
-	my $depth = $re =~ tr/*/*/;
-	if ($depth != $temp =~ tr/*/*/) {
-		die "Only one set of wildcard directories " .
-			"(e.g. '*' or '*/*/*') is supported: '$glob'\n";
+	my (@left, @right, @patterns);
+	my $state = "left";
+	my $die_msg = "Only one set of wildcard directories " .
+				"(e.g. '*' or '*/*/*') is supported: '$glob'\n";
+	for my $part (split(m|/|, $glob)) {
+		if ($part =~ /\*/ && $part ne "*") {
+			die "Invalid pattern in '$glob': $part\n";
+		} elsif ($pattern_ok && $part =~ /[{}]/ &&
+			 $part !~ /^\{[^{}]+\}/) {
+			die "Invalid pattern in '$glob': $part\n";
+		}
+		if ($part eq "*") {
+			die $die_msg if $state eq "right";
+			$state = "pattern";
+			push(@patterns, "[^/]*");
+		} elsif ($pattern_ok && $part =~ /^\{(.*)\}$/) {
+			die $die_msg if $state eq "right";
+			$state = "pattern";
+			my $p = quotemeta($1);
+			$p =~ s/\\,/|/g;
+			push(@patterns, "(?:$p)");
+		} else {
+			if ($state eq "left") {
+				push(@left, $part);
+			} else {
+				push(@right, $part);
+				$state = "right";
+			}
+		}
 	}
+	my $depth = @patterns;
 	if ($depth == 0) {
-		die "One '*' is needed for glob: '$glob'\n";
-	}
-	$re =~ s!\*!\[^/\]*!g;
-	$re = quotemeta($left) . "($re)" . quotemeta($right);
-	if (length $left && !($left =~ s!/+$!!g)) {
-		die "Missing trailing '/' on left side of: '$glob' ($left)\n";
-	}
-	if (length $right && !($right =~ s!^/+!!g)) {
-		die "Missing leading '/' on right side of: '$glob' ($right)\n";
+		die "One '*' is needed in glob: '$glob'\n";
 	}
+	my $left = join('/', @left);
+	my $right = join('/', @right);
+	$re = join('/', @patterns);
+	$re = join('\/',
+		   grep(length, quotemeta($left), "($re)", quotemeta($right)));
 	my $left_re = qr/^\/\Q$left\E(\/|$)/;
 	bless { left => $left, right => $right, left_regex => $left_re,
 	        regex => qr/$re/, glob => $glob, depth => $depth }, $class;

File t/t9151-svn-mergeinfo.sh

 	[ -z "$bad_non_merges" ]
 	'
 
-test_expect_success 'everything got merged in the end' '
+test_expect_failure 'everything got merged in the end' '
 	unmerged=$(git rev-list --all --not master)
 	[ -z "$unmerged" ]
 	'

File t/t9151/make-svnmerge-dump

 cd foo
 mkdir trunk
 mkdir branches
-svn add trunk branches
-i=$(commit $i "Setup trunk and branches")
+mkdir tags
+svn add trunk branches tags
+i=$(commit $i "Setup trunk, branches, and tags")
 
 git cat-file blob 6683463e:Makefile > trunk/Makefile
 svn add trunk/Makefile 
 i=$(commit $i "non-merge right to trunk 2")
 cd ..
 
+say "Adding subdirectory to LEFT"
+svn update
+cd branches/left
+mkdir subdir
+echo "Yeehaw" > subdir/cowboy
+svn add subdir
+i=$(commit $i "add subdirectory to left branch")
+cd ../../
+
+say "Merging LEFT to TRUNK"
+svn update
+cd trunk
+svn merge ../branches/left --accept postpone
+i=$(commit $i "merge left to trunk")
+cd ..
+
+say "Make PARTIAL branch"
+svn update
+i=$(commit $i "make partial branch")
+svn cp trunk/subdir branches/partial
+
+say "Make a commit to PARTIAL"
+svn update
+cd branches/partial
+echo "racecar" > palindromes
+svn add palindromes
+i=$(commit $i "partial update")
+cd ../../
+
+say "Merge PARTIAL to TRUNK"
+svn update
+cd trunk/subdir
+svn merge ../../branches/partial --accept postpone
+i=$(commit $i "merge partial to trunk")
+cd ../../
+
+say "Tagging trunk"
+svn update
+i=$(commit $i "tagging v1.0")
+svn cp trunk tags/v1.0
+
+say "Branching BUGFIX from v1.0"
+svn update
+i=$(commit $i "make bugfix branch from tag")
+svn cp tags/v1.0 branches/bugfix
+
+say "Make a commit to BUGFIX"
+svn update
+cd branches/bugfix/
+echo "kayak" >> subdir/palindromes
+i=$(commit $i "commit to bugfix")
+cd ../../
+
+say "Merge BUGFIX to TRUNK"
+svn update
+cd trunk
+svn merge ../branches/bugfix/ --accept postpone
+i=$(commit $i "Merge BUGFIX to TRUNK")
+cd ..
+
 cd ..
 svnadmin dump foo.svn > svn-mergeinfo.dump
 

File t/t9151/svn-mergeinfo.dump

 SVN-fs-dump-format-version: 2
 
-UUID: 64142547-0943-4db2-836a-d1e1eb2f9924
+UUID: d6191530-2693-4a8e-98e7-b194d4c3edd8
 
 Revision-number: 0
 Prop-content-length: 56
 K 8
 svn:date
 V 27
-2009-12-19T16:17:51.232640Z
+2010-01-19T04:14:02.832406Z
 PROPS-END
 
 Revision-number: 1
-Prop-content-length: 128
-Content-length: 128
+Prop-content-length: 134
+Content-length: 134
 
 K 7
 svn:log
-V 29
-(r1) Setup trunk and branches
+V 36
+(r1) Setup trunk, branches, and tags
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:51.831965Z
+2010-01-19T04:14:03.055172Z
 PROPS-END
 
 Node-path: branches
 PROPS-END
 
 
+Node-path: tags
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
 Node-path: trunk
 Node-kind: dir
 Node-action: add
 
 
 Revision-number: 2
-Prop-content-length: 112
-Content-length: 112
+Prop-content-length: 111
+Content-length: 111
 
 K 7
 svn:log
 (r2) ancestor
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:52.300075Z
+2010-01-19T04:14:04.064506Z
 PROPS-END
 
 Node-path: trunk/Makefile
 
 
 Revision-number: 3
-Prop-content-length: 120
-Content-length: 120
+Prop-content-length: 119
+Content-length: 119
 
 K 7
 svn:log
 (r3) make left branch
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:52.768800Z
+2010-01-19T04:14:06.040389Z
 PROPS-END
 
 Node-path: branches/left
 
 
 Revision-number: 4
-Prop-content-length: 121
-Content-length: 121
+Prop-content-length: 120
+Content-length: 120
 
 K 7
 svn:log
 (r4) make right branch
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:53.177879Z
+2010-01-19T04:14:08.040905Z
 PROPS-END
 
 Node-path: branches/right
 
 
 Revision-number: 5
-Prop-content-length: 117
-Content-length: 117
+Prop-content-length: 116
+Content-length: 116
 
 K 7
 svn:log
 (r5) left update 1
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:53.604691Z
+2010-01-19T04:14:09.049169Z
 PROPS-END
 
 Node-path: branches/left/Makefile
 
 
 Revision-number: 6
-Prop-content-length: 118
-Content-length: 118
+Prop-content-length: 117
+Content-length: 117
 
 K 7
 svn:log
 (r6) right update 1
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:54.063555Z
+2010-01-19T04:14:10.049350Z
 PROPS-END
 
 Node-path: branches/right/Makefile
 
 
 Revision-number: 7
-Prop-content-length: 117
-Content-length: 117
+Prop-content-length: 116
+Content-length: 116
 
 K 7
 svn:log
 (r7) left update 2
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:54.523904Z
+2010-01-19T04:14:11.049209Z
 PROPS-END
 
 Node-path: branches/left/Makefile
 
 
 Revision-number: 8
-Prop-content-length: 117
-Content-length: 117
+Prop-content-length: 116
+Content-length: 116
 
 K 7
 svn:log
 (r8) left update 3
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:54.975970Z
+2010-01-19T04:14:12.049234Z
 PROPS-END
 
 Node-path: branches/left/Makefile
 
 
 Revision-number: 9
-Prop-content-length: 124
-Content-length: 124
+Prop-content-length: 123
+Content-length: 123
 
 K 7
 svn:log
 (r9) make left sub-branch
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:55.459904Z
+2010-01-19T04:14:14.040894Z
 PROPS-END
 
 Node-path: branches/left-sub
 
 
 Revision-number: 10
-Prop-content-length: 129
-Content-length: 129
+Prop-content-length: 128
+Content-length: 128
 
 K 7
 svn:log
 (r10) left sub-branch update 1
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:55.862113Z
+2010-01-19T04:14:15.049935Z
 PROPS-END
 
 Node-path: branches/left-sub/README
 
 
 Revision-number: 11
-Prop-content-length: 126
-Content-length: 126
+Prop-content-length: 125
+Content-length: 125
 
 K 7
 svn:log
 (r11) Merge left to trunk 1
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:56.413416Z
+2010-01-19T04:14:18.056594Z
 PROPS-END
 
 Node-path: trunk
 
 
 Revision-number: 12
-Prop-content-length: 118
-Content-length: 118
+Prop-content-length: 117
+Content-length: 117
 
 K 7
 svn:log
 (r12) left update 4
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:56.831014Z
+2010-01-19T04:14:19.049620Z
 PROPS-END
 
 Node-path: branches/left/zlonk
 
 
 Revision-number: 13
-Prop-content-length: 119
-Content-length: 119
+Prop-content-length: 118
+Content-length: 118
 
 K 7
 svn:log
 (r13) right update 2
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:57.341143Z
+2010-01-19T04:14:20.049659Z
 PROPS-END
 
 Node-path: branches/right/bang
 
 
 Revision-number: 14
-Prop-content-length: 141
-Content-length: 141
+Prop-content-length: 140
+Content-length: 140
 
 K 7
 svn:log
 (r14) Cherry-pick right 2 commits to trunk
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:57.841851Z
+2010-01-19T04:14:23.041991Z
 PROPS-END
 
 Node-path: trunk
 
 
 Revision-number: 15
-Prop-content-length: 127
-Content-length: 127
+Prop-content-length: 126
+Content-length: 126
 
 K 7
 svn:log
 (r15) Merge right to trunk 1
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:58.368520Z
+2010-01-19T04:14:26.054456Z
 PROPS-END
 
 Node-path: trunk
 
 
 Revision-number: 16
-Prop-content-length: 119
-Content-length: 119
+Prop-content-length: 118
+Content-length: 118
 
 K 7
 svn:log
 (r16) right update 3
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:58.779056Z
+2010-01-19T04:14:27.049955Z
 PROPS-END
 
 Node-path: branches/right/urkkk
 
 
 Revision-number: 17
-Prop-content-length: 119
-Content-length: 119
+Prop-content-length: 118
+Content-length: 118
 
 K 7
 svn:log
 (r17) trunk update 1
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:59.221851Z
+2010-01-19T04:14:28.049615Z
 PROPS-END
 
 Node-path: trunk/vronk
 
 
 Revision-number: 18
-Prop-content-length: 135
-Content-length: 135
+Prop-content-length: 134
+Content-length: 134
 
 K 7
 svn:log
 (r18) Merge right to left sub-branch
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:17:59.781666Z
+2010-01-19T04:14:31.061460Z
 PROPS-END
 
 Node-path: branches/left-sub
 
 
 Revision-number: 19
-Prop-content-length: 129
-Content-length: 129
+Prop-content-length: 128
+Content-length: 128
 
 K 7
 svn:log
 (r19) left sub-branch update 2
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:18:00.200531Z
+2010-01-19T04:14:32.049244Z
 PROPS-END
 
 Node-path: branches/left-sub/wham_eth
 
 
 Revision-number: 20
-Prop-content-length: 118
-Content-length: 118
+Prop-content-length: 117
+Content-length: 117
 
 K 7
 svn:log
 (r20) left update 5
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:18:00.659636Z
+2010-01-19T04:14:33.049332Z
 PROPS-END
 
 Node-path: branches/left/glurpp
 
 
 Revision-number: 21
-Prop-content-length: 147
-Content-length: 147
+Prop-content-length: 146
+Content-length: 146
 
 K 7
 svn:log
 (r21) Cherry-pick left sub-branch commit to left
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:18:01.194402Z
+2010-01-19T04:14:36.041839Z
 PROPS-END
 
 Node-path: branches/left
 
 
 Revision-number: 22
-Prop-content-length: 134
-Content-length: 134
+Prop-content-length: 133
+Content-length: 133
 
 K 7
 svn:log
 (r22) Merge left sub-branch to left
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:18:01.679218Z
+2010-01-19T04:14:39.045014Z
 PROPS-END
 
 Node-path: branches/left
 
 
 Revision-number: 23
-Prop-content-length: 126
-Content-length: 126
+Prop-content-length: 125
+Content-length: 125
 
 K 7
 svn:log
 (r23) Merge left to trunk 2
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:18:02.212349Z
+2010-01-19T04:14:42.052798Z
 PROPS-END
 
 Node-path: trunk
 
 
 Revision-number: 24
-Prop-content-length: 131
-Content-length: 131
+Prop-content-length: 130
+Content-length: 130
 
 K 7
 svn:log
 (r24) non-merge right to trunk 2
 K 10
 svn:author
-V 4
-samv
+V 3
+adm
 K 8
 svn:date
 V 27
-2009-12-19T16:18:02.672148Z
+2010-01-19T04:14:44.038434Z
 PROPS-END
 
 Node-path: trunk
 PROPS-END
 
 
+Revision-number: 25
+Prop-content-length: 135
+Content-length: 135
+
+K 7
+svn:log
+V 37
+(r25) add subdirectory to left branch
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-01-19T04:14:46.052649Z
+PROPS-END
+
+Node-path: branches/left/subdir
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: branches/left/subdir/cowboy
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 7
+Text-content-md5: f1d6530278ad409e68cc675476ad995f
+Text-content-sha1: 732d9e3e5c391ffd767a98b45ddcc848de778cea
+Content-length: 17
+
+PROPS-END
+Yeehaw
+
+
+Revision-number: 26
+Prop-content-length: 123
+Content-length: 123
+
+K 7
+svn:log
+V 25
+(r26) merge left to trunk
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-01-19T04:14:49.040783Z
+PROPS-END
+
+Node-path: trunk
+Node-kind: dir
+Node-action: change
+Prop-content-length: 99
+Content-length: 99
+
+K 13
+svn:mergeinfo
+V 64
+/branches/left:2-25
+/branches/left-sub:4-19
+/branches/right:2-22
+PROPS-END
+
+
+Node-path: trunk/subdir
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 25
+Node-copyfrom-path: branches/left/subdir
+
+
+Revision-number: 27
+Prop-content-length: 118
+Content-length: 118
+
+K 7
+svn:log
+V 20
+(r28) partial update
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-01-19T04:14:53.049037Z
+PROPS-END
+
+Node-path: branches/partial
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 26
+Node-copyfrom-path: trunk/subdir
+
+
+Node-path: branches/partial/palindromes
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 8
+Text-content-md5: 5d1c2024fb5efc4eef812856df1b080c
+Text-content-sha1: 5f8509ddd14c91a52864dd1447344e706f9bbc69
+Content-length: 18
+
+PROPS-END
+racecar
+
+
+Revision-number: 28
+Prop-content-length: 126
+Content-length: 126
+
+K 7
+svn:log
+V 28
+(r29) merge partial to trunk
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-01-19T04:14:56.041526Z
+PROPS-END
+
+Node-path: trunk/subdir
+Node-kind: dir
+Node-action: change
+Prop-content-length: 142
+Content-length: 142
+
+K 13
+svn:mergeinfo
+V 106
+/branches/left/subdir:2-25
+/branches/left-sub/subdir:4-19
+/branches/partial:27
+/branches/right/subdir:2-22
+PROPS-END
+
+
+Node-path: trunk/subdir/palindromes
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 27
+Node-copyfrom-path: branches/partial/palindromes
+Text-copy-source-md5: 5d1c2024fb5efc4eef812856df1b080c
+Text-copy-source-sha1: 5f8509ddd14c91a52864dd1447344e706f9bbc69
+
+
+Revision-number: 29
+Prop-content-length: 131
+Content-length: 131
+
+K 7
+svn:log
+V 33
+(r31) make bugfix branch from tag
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-01-19T04:15:00.039761Z
+PROPS-END
+
+Node-path: tags/v1.0
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 28
+Node-copyfrom-path: trunk
+
+
+Revision-number: 30
+Prop-content-length: 120
+Content-length: 120
+
+K 7
+svn:log
+V 22
+(r32) commit to bugfix
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-01-19T04:15:03.043218Z
+PROPS-END
+
+Node-path: branches/bugfix
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 29
+Node-copyfrom-path: tags/v1.0
+
+
+Node-path: branches/bugfix/subdir/palindromes
+Node-kind: file
+Node-action: change
+Text-content-length: 14
+Text-content-md5: 3b12d98578a3f4320ba97e66da54fe5f
+Text-content-sha1: 672931c9e8ac2c408209efab2f015638b6d64042
+Content-length: 14
+
+racecar
+kayak
+
+
+Revision-number: 31
+Prop-content-length: 125
+Content-length: 125
+
+K 7
+svn:log
+V 27
+(r33) Merge BUGFIX to TRUNK
+K 10
+svn:author
+V 3
+adm
+K 8
+svn:date
+V 27
+2010-01-19T04:15:06.043723Z
+PROPS-END
+
+Node-path: trunk
+Node-kind: dir
+Node-action: change
+Prop-content-length: 133
+Content-length: 133
+
+K 13
+svn:mergeinfo
+V 98
+/branches/bugfix:30
+/branches/left:2-25
+/branches/left-sub:4-19
+/branches/right:2-22
+/tags/v1.0:29
+PROPS-END
+
+
+Node-path: trunk/subdir
+Node-kind: dir
+Node-action: change
+Prop-content-length: 190
+Content-length: 190
+
+K 13
+svn:mergeinfo
+V 154
+/branches/bugfix/subdir:30
+/branches/left/subdir:2-25
+/branches/left-sub/subdir:4-19
+/branches/partial:27
+/branches/right/subdir:2-22
+/tags/v1.0/subdir:29
+PROPS-END
+
+
+Node-path: trunk/subdir/palindromes
+Node-kind: file
+Node-action: change
+Text-content-length: 14
+Text-content-md5: 3b12d98578a3f4320ba97e66da54fe5f
+Text-content-sha1: 672931c9e8ac2c408209efab2f015638b6d64042
+Content-length: 14
+
+racecar
+kayak
+
+

File t/t9153-git-svn-rewrite-uuid.sh

+#!/bin/sh
+#
+# Copyright (c) 2010 Jay Soffian
+#
+
+test_description='git svn --rewrite-uuid test'
+
+. ./lib-git-svn.sh
+
+uuid=6cc8ada4-5932-4b4a-8242-3534ed8a3232
+
+test_expect_success 'load svn repo' "
+	svnadmin load -q '$rawsvnrepo' < '$TEST_DIRECTORY/t9153/svn.dump' &&
+	git svn init --minimize-url --rewrite-uuid='$uuid' '$svnrepo' &&
+	git svn fetch
+	"
+
+test_expect_success 'verify uuid' "
+	git cat-file commit refs/remotes/git-svn~0 | \
+	   grep '^${git_svn_id}: .*@2 $uuid$' &&
+	git cat-file commit refs/remotes/git-svn~1 | \
+	   grep '^${git_svn_id}: .*@1 $uuid$'
+	"
+
+test_done

File t/t9153/svn.dump

+SVN-fs-dump-format-version: 2
+
+UUID: b4885626-c94f-4a6c-b179-00c030fc68e8
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2010-01-23T06:41:03.908576Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 109
+Content-length: 109
+
+K 7
+svn:log
+V 11
+initial foo
+K 10
+svn:author
+V 3
+jay
+K 8
+svn:date
+V 27
+2010-01-23T06:41:48.353776Z
+PROPS-END
+
+Node-path: foo
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 4
+Text-content-md5: d3b07384d113edec49eaa6238ad5ff00
+Text-content-sha1: f1d2d2f924e986ac86fdf7b36c94bcdf32beec15
+Content-length: 14
+
+PROPS-END
+foo
+
+
+Revision-number: 2
+Prop-content-length: 110
+Content-length: 110
+
+K 7
+svn:log
+V 12
+now with bar
+K 10
+svn:author
+V 3
+jay
+K 8
+svn:date
+V 27
+2010-01-23T06:42:14.214640Z
+PROPS-END
+
+Node-path: foo
+Node-kind: file
+Node-action: change
+Text-content-length: 8
+Text-content-md5: f47c75614087a8dd938ba4acff252494
+Text-content-sha1: 4e48e2c9a3d2ca8a708cb0cc545700544efb5021
+Content-length: 8
+
+foo
+bar
+
+

File t/t9154-git-svn-fancy-glob.sh

+#!/bin/sh
+#
+# Copyright (c) 2010 Jay Soffian
+#
+
+test_description='git svn fancy glob test'
+
+. ./lib-git-svn.sh
+
+test_expect_success 'load svn repo' "
+	svnadmin load -q '$rawsvnrepo' < '$TEST_DIRECTORY/t9154/svn.dump' &&
+	git svn init --minimize-url -T trunk '$svnrepo' &&
+	git svn fetch
+	"
+
+test_expect_success 'add red branch' "
+	git config svn-remote.svn.branches 'branches/{red}:refs/remotes/*' &&
+	git svn fetch &&
+	git rev-parse refs/remotes/red &&
+	test_must_fail git rev-parse refs/remotes/green &&
+	test_must_fail git rev-parse refs/remotes/blue
+	"
+
+test_expect_success 'add green branch' "
+	GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev &&
+	git config svn-remote.svn.branches 'branches/{red,green}:refs/remotes/*' &&
+	git svn fetch &&
+	git rev-parse refs/remotes/red &&
+	git rev-parse refs/remotes/green &&
+	test_must_fail git rev-parse refs/remotes/blue
+	"
+
+test_expect_success 'add all branches' "
+	GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev &&
+	git config svn-remote.svn.branches 'branches/*:refs/remotes/*' &&
+	git svn fetch &&
+	git rev-parse refs/remotes/red &&
+	git rev-parse refs/remotes/green &&
+	git rev-parse refs/remotes/blue
+	"
+
+test_done

File t/t9154/svn.dump

+SVN-fs-dump-format-version: 2
+
+UUID: a18093a0-5f0b-44e0-8d88-8911ac7078db
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2010-01-23T07:40:25.660053Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 104
+Content-length: 104
+
+K 7
+svn:log
+V 7
+initial
+K 10
+svn:author
+V 3
+jay
+K 8
+svn:date
+V 27
+2010-01-23T07:41:33.636365Z
+PROPS-END
+
+Node-path: trunk
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: trunk/foo
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 4
+Text-content-md5: d3b07384d113edec49eaa6238ad5ff00
+Text-content-sha1: f1d2d2f924e986ac86fdf7b36c94bcdf32beec15
+Content-length: 14
+
+PROPS-END
+foo
+
+
+Revision-number: 2
+Prop-content-length: 110
+Content-length: 110
+
+K 7
+svn:log
+V 12
+add branches
+K 10
+svn:author
+V 3
+jay
+K 8
+svn:date
+V 27
+2010-01-23T07:42:37.290694Z
+PROPS-END
+
+Node-path: branches
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: branches/blue
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 1
+Node-copyfrom-path: trunk
+
+
+Node-path: branches/green
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 1
+Node-copyfrom-path: trunk
+
+
+Node-path: branches/red
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 1
+Node-copyfrom-path: trunk
+
+
+Revision-number: 3
+Prop-content-length: 108
+Content-length: 108
+
+K 7
+svn:log
+V 10
+red change
+K 10
+svn:author
+V 3
+jay
+K 8
+svn:date
+V 27
+2010-01-23T07:43:02.208918Z
+PROPS-END
+
+Node-path: branches/red/foo
+Node-kind: file
+Node-action: change
+Text-content-length: 8
+Text-content-md5: 64c3c8cf7d0233ab7627623a68888bd1
+Text-content-sha1: 95a0492027876adfd3891ec71ee37b79ee44d640
+Content-length: 8
+
+foo
+red
+
+
+Revision-number: 4
+Prop-content-length: 110
+Content-length: 110
+
+K 7
+svn:log
+V 12
+green change
+K 10
+svn:author
+V 3
+jay
+K 8
+svn:date
+V 27
+2010-01-23T07:43:15.746586Z
+PROPS-END
+
+Node-path: branches/green/foo
+Node-kind: file
+Node-action: change
+Text-content-length: 10
+Text-content-md5: 0209b6450891abc033d5eaaa9d3a8023
+Text-content-sha1: 87fc3bef9faeec48c0cd61dfc9851db377fdccf7
+Content-length: 10
+
+foo
+green
+
+
+Revision-number: 5
+Prop-content-length: 109
+Content-length: 109
+
+K 7
+svn:log
+V 11
+blue change
+K 10
+svn:author
+V 3
+jay
+K 8
+svn:date
+V 27
+2010-01-23T07:43:29.364811Z
+PROPS-END
+
+Node-path: branches/blue/foo
+Node-kind: file
+Node-action: change
+Text-content-length: 9
+Text-content-md5: 9fbe4c13d0bae86386ae5209b2e6b275
+Text-content-sha1: cc4575083459a16f9aaef796c4a2456d64691ba0
+Content-length: 9
+
+foo
+blue
+
+
+Revision-number: 6
+Prop-content-length: 110
+Content-length: 110
+
+K 7
+svn:log
+V 12
+trunk change
+K 10
+svn:author
+V 3
+jay
+K 8
+svn:date
+V 27
+2010-01-23T07:44:01.313130Z
+PROPS-END
+
+Node-path: trunk/foo
+Node-kind: file
+Node-action: change
+Text-content-length: 10
+Text-content-md5: 1c4db977d7a57c3bae582aab87948516
+Text-content-sha1: 469c08df449e702cf2a1fe746244a9ef3f837fad
+Content-length: 10
+
+foo
+trunk
+
+