git-svn: allow UUID to be manually remapped via rewriteUUID
In certain situations it may be necessary to manually remap an svn
repostitory UUID. For example:
                  o--- [git-svn clone]
                 /
[origin svn repo]
                 \
                  o--- [svnsync clone]
Imagine that only "git-svn clone" and "svnsync clone" are made available
to external users. Furthur, "git-svn clone" contains only trunk, and for
reasons unknown, "svnsync clone" is missing the revision properties that
normally provide the origin svn repo's UUID.
A git user who has cloned the "git-svn clone" repo now wishes to use
git-svn to pull in the missing branches from the "synsync clone" repo.
In order for git-svn to get the history correct for those branches,
it needs to know the origin svn repo's UUID. Hence rewriteUUID.
Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Acked-by: Eric Wong <normalperson@yhbt.net>
			
			
				maint
			
			
		
							parent
							
								
									c79f1189bc
								
							
						
					
					
						commit
						3e18ce1ac3
					
				|  | @ -62,6 +62,8 @@ COMMANDS | ||||||
| 	Set the 'useSvnsyncProps' option in the [svn-remote] config. | 	Set the 'useSvnsyncProps' option in the [svn-remote] config. | ||||||
| --rewrite-root=<URL>;; | --rewrite-root=<URL>;; | ||||||
| 	Set the 'rewriteRoot' option in the [svn-remote] config. | 	Set the 'rewriteRoot' option in the [svn-remote] config. | ||||||
|  | --rewrite-uuid=<UUID>;; | ||||||
|  | 	Set the 'rewriteUUID' option in the [svn-remote] config. | ||||||
| --username=<USER>;; | --username=<USER>;; | ||||||
| 	For transports that SVN handles authentication for (http, | 	For transports that SVN handles authentication for (http, | ||||||
| 	https, and plain svn), specify the username.  For other | 	https, and plain svn), specify the username.  For other | ||||||
|  | @ -629,6 +631,12 @@ svn-remote.<name>.rewriteRoot:: | ||||||
| 	the repository with a public http:// or svn:// URL in the | 	the repository with a public http:// or svn:// URL in the | ||||||
| 	metadata so users of it will see the public URL. | 	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:: | svn.brokenSymlinkWorkaround:: | ||||||
| 	This disables potentially expensive checks to workaround | 	This disables potentially expensive checks to workaround | ||||||
| 	broken symlinks checked into SVN by broken clients.  Set this | 	broken symlinks checked into SVN by broken clients.  Set this | ||||||
|  | @ -638,13 +646,14 @@ svn.brokenSymlinkWorkaround:: | ||||||
| 	revision fetched.  If unset, 'git svn' assumes this option to | 	revision fetched.  If unset, 'git svn' assumes this option to | ||||||
| 	be "true". | 	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 | options all affect the metadata generated and used by 'git svn'; they | ||||||
| *must* be set in the configuration file before any history is imported | *must* be set in the configuration file before any history is imported | ||||||
| and these settings should never be changed once they are set. | and these settings should never be changed once they are set. | ||||||
|  |  | ||||||
| Additionally, only one of these four options can be used per-svn-remote | Additionally, only one of these options can be used per svn-remote | ||||||
| section because they affect the 'git-svn-id:' metadata line. | section because they affect the 'git-svn-id:' metadata line, except | ||||||
|  | for rewriteRoot and rewriteUUID which can be used together. | ||||||
|  |  | ||||||
|  |  | ||||||
| BASIC EXAMPLES | BASIC EXAMPLES | ||||||
|  |  | ||||||
							
								
								
									
										33
									
								
								git-svn.perl
								
								
								
								
							
							
						
						
									
										33
									
								
								git-svn.perl
								
								
								
								
							|  | @ -115,6 +115,7 @@ my %init_opts = ( 'template=s' => \$_template, 'shared:s' => \$_shared, | ||||||
| 		  'use-svm-props' => sub { $icv{useSvmProps} = 1 }, | 		  'use-svm-props' => sub { $icv{useSvmProps} = 1 }, | ||||||
| 		  'use-svnsync-props' => sub { $icv{useSvnsyncProps} = 1 }, | 		  'use-svnsync-props' => sub { $icv{useSvnsyncProps} = 1 }, | ||||||
| 		  'rewrite-root=s' => sub { $icv{rewriteRoot} = $_[1] }, | 		  'rewrite-root=s' => sub { $icv{rewriteRoot} = $_[1] }, | ||||||
|  | 		  'rewrite-uuid=s' => sub { $icv{rewriteUUID} = $_[1] }, | ||||||
|                   %remote_opts ); |                   %remote_opts ); | ||||||
| my %cmt_opts = ( 'edit|e' => \$_edit, | my %cmt_opts = ( 'edit|e' => \$_edit, | ||||||
| 		'rmdir' => \$SVN::Git::Editor::_rmdir, | 		'rmdir' => \$SVN::Git::Editor::_rmdir, | ||||||
|  | @ -2207,6 +2208,10 @@ sub svnsync { | ||||||
| 		die "Can't have both 'useSvnsyncProps' and 'rewriteRoot' ", | 		die "Can't have both 'useSvnsyncProps' and 'rewriteRoot' ", | ||||||
| 		    "options set!\n"; | 		    "options set!\n"; | ||||||
| 	} | 	} | ||||||
|  | 	if ($self->rewrite_uuid) { | ||||||
|  | 		die "Can't have both 'useSvnsyncProps' and 'rewriteUUID' ", | ||||||
|  | 		    "options set!\n"; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	my $svnsync; | 	my $svnsync; | ||||||
| 	# see if we have it in our config, first: | 	# see if we have it in our config, first: | ||||||
|  | @ -2488,6 +2493,20 @@ sub rewrite_root { | ||||||
| 	$self->{-rewrite_root} = $rwr; | 	$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 { | sub metadata_url { | ||||||
| 	my ($self) = @_; | 	my ($self) = @_; | ||||||
| 	($self->rewrite_root || $self->{url}) . | 	($self->rewrite_root || $self->{url}) . | ||||||
|  | @ -3306,6 +3325,10 @@ sub make_log_entry { | ||||||
| 			die "Can't have both 'useSvmProps' and 'rewriteRoot' ", | 			die "Can't have both 'useSvmProps' and 'rewriteRoot' ", | ||||||
| 			    "options set!\n"; | 			    "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; | 		my ($uuid, $r) = $headrev =~ m{^([a-f\d\-]{30,}):(\d+)$}i; | ||||||
| 		# we don't want "SVM: initializing mirror for junk" ... | 		# we don't want "SVM: initializing mirror for junk" ... | ||||||
| 		return undef if $r == 0; | 		return undef if $r == 0; | ||||||
|  | @ -3336,10 +3359,10 @@ sub make_log_entry { | ||||||
| 	} else { | 	} else { | ||||||
| 		my $url = $self->metadata_url; | 		my $url = $self->metadata_url; | ||||||
| 		remove_username($url); | 		remove_username($url); | ||||||
| 		$log_entry{metadata} = "$url\@$rev " . | 		my $uuid = $self->rewrite_uuid || $self->ra->get_uuid; | ||||||
| 		                       $self->ra->get_uuid; | 		$log_entry{metadata} = "$url\@$rev " . $uuid; | ||||||
| 		$email ||= "$author\@" . $self->ra->get_uuid; | 		$email ||= "$author\@" . $uuid; | ||||||
| 		$commit_email ||= "$author\@" . $self->ra->get_uuid; | 		$commit_email ||= "$author\@" . $uuid; | ||||||
| 	} | 	} | ||||||
| 	$log_entry{name} = $name; | 	$log_entry{name} = $name; | ||||||
| 	$log_entry{email} = $email; | 	$log_entry{email} = $email; | ||||||
|  | @ -3421,7 +3444,7 @@ sub rebuild { | ||||||
| 				'--'); | 				'--'); | ||||||
| 	my $metadata_url = $self->metadata_url; | 	my $metadata_url = $self->metadata_url; | ||||||
| 	remove_username($metadata_url); | 	remove_username($metadata_url); | ||||||
| 	my $svn_uuid = $self->ra_uuid; | 	my $svn_uuid = $self->rewrite_uuid || $self->ra_uuid; | ||||||
| 	my $c; | 	my $c; | ||||||
| 	while (<$log>) { | 	while (<$log>) { | ||||||
| 		if ( m{^commit ($::sha1)$} ) { | 		if ( m{^commit ($::sha1)$} ) { | ||||||
|  |  | ||||||
|  | @ -0,0 +1,25 @@ | ||||||
|  | #!/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 | ||||||
|  | @ -0,0 +1,75 @@ | ||||||
|  | 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 | ||||||
|  |  | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Jay Soffian
						Jay Soffian