All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] git-svn: re-map repository URLs and UUIDs on SVK mirror paths
@ 2007-02-10 23:34 Sam Vilain
  2007-02-11  4:55 ` Eric Wong
  2007-02-13 22:21 ` Eric Wong
  0 siblings, 2 replies; 5+ messages in thread
From: Sam Vilain @ 2007-02-10 23:34 UTC (permalink / raw)
  To: Eric Wong; +Cc: git

If an SVN revision has a property, "svm:headrev", it is likely that
the revision was created by SVN::Mirror (a part of SVK).  The property
contains a repository UUID and a revision.  We want to make it look
like we are mirroring the original URL, so introduce a helper function
that returns the original identity URL and UUID, and use it when
generating commit messages.
---
 git-svn.perl |   39 +++++++++++++++++++++++++++++++++------
 1 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index 59d9faf..5b0d8b7 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1055,10 +1055,23 @@ sub do_git_commit {
 	defined(my $pid = open3(my $msg_fh, my $out_fh, '>&STDERR', @exec))
 	                                                           or croak $!;
 	print $msg_fh $log_entry->{log} or croak $!;
+	my $at = "";
 	unless ($_no_metadata) {
-		print $msg_fh "\ngit-svn-id: ", $self->full_url, '@',
-		              $log_entry->{revision}, ' ',
-		              $self->ra->uuid, "\n" or croak $!;
+		my $full_url = $self->full_url;
+		my $revision = $log_entry->{revision};
+		my $uuid = $self->ra->uuid;
+		my $repo_id = $Git::SVN::default_repo_id;
+		$DB::single = 1;
+		if ( $log_entry->{headrev} ) {
+			my ($from_uuid, $rev) = $log_entry->{headrev} =~ m{^([a-f0-9\-]{30,}):(\d+)$};
+			($full_url, $uuid) = get_svm_url( $repo_id, $full_url, $uuid );
+			die "UUID mismatch on SVM path : $uuid vs $from_uuid"
+				if $from_uuid ne $uuid;
+			$revision = $rev;
+			$at = " (\@$rev)";
+		}
+		print $msg_fh "\ngit-svn-id: ", $full_url, '@',
+		              $revision, ' ', $uuid, "\n" or croak $!;
 	}
 	$msg_fh->flush == 0 or croak $!;
 	close $msg_fh or croak $!;
@@ -1074,7 +1087,7 @@ sub do_git_commit {
 
 	$self->{last_rev} = $log_entry->{revision};
 	$self->{last_commit} = $commit;
-	print "r$log_entry->{revision} = $commit ($self->{ref_id})\n";
+	print "r$log_entry->{revision}$at = $commit ($self->{ref_id})\n";
 	if (defined $_repack && (--$_repack_nr == 0)) {
 		$_repack_nr = $_repack;
 		# repack doesn't use any arguments with spaces in them, does it?
@@ -1284,8 +1297,9 @@ sub make_log_entry {
 	my $rp = $self->ra->rev_proplist($rev);
 	foreach (sort keys %$rp) {
 		my $v = $rp->{$_};
-		if (/^svn:(author|date|log)$/) {
-			$log_entry{$1} = $v;
+		$DB::single = 1 if /svm:/;
+		if (/^(?:svn:(author|date|log)|svm:(headrev))$/) {
+			$log_entry{$1||$2} = $v;
 		} else {
 			print $un "  rev_prop: ", uri_encode($_), ' ',
 		                  uri_encode($v), "\n";
@@ -1492,6 +1506,19 @@ sub uri_encode {
 	$f
 }
 
+our %svm_urls;
+sub get_svm_url {
+	my ($repo_id, $url, $uuid) = @_;
+	my $spec = $url.":".$uuid;
+	if (!exists $svm_urls{$spec}) {
+		my $source = `git-repo-config --get svn-remote.$repo_id.source`;
+		my $svmuuid = `git-repo-config --get svn-remote.$repo_id.uuid`;
+		chomp for ($source, $svmuuid);
+		$svm_urls{$spec}=[$source,$svmuuid];
+	}
+	($url,$uuid) = @{$svm_urls{$spec}};
+}
+
 package Git::SVN::Prompt;
 use strict;
 use warnings;
-- 
1.5.0.rc3.g3e023

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] git-svn: re-map repository URLs and UUIDs on SVK mirror paths
  2007-02-10 23:34 [PATCH] git-svn: re-map repository URLs and UUIDs on SVK mirror paths Sam Vilain
@ 2007-02-11  4:55 ` Eric Wong
  2007-02-11  9:41   ` Eric Wong
  2007-02-13 22:21 ` Eric Wong
  1 sibling, 1 reply; 5+ messages in thread
From: Eric Wong @ 2007-02-11  4:55 UTC (permalink / raw)
  To: Sam Vilain; +Cc: git

Note: these patches (both Sam's and mine below) are not meant for
master, but the development/semi-rewrite version of git-svn at
http://git.bogomips.org/git-svn.git

Sam: here's my take on your patches.  I'll add support for
per-[svn-remote "..."] configuration that we talked about
on IRC in a separate patch.

>From 45fd937a6129aebc9cad1b7128f2811dd32af454 Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Sat, 10 Feb 2007 20:46:50 -0800
Subject: [PATCH] git-svn: add support for SVN::Mirror/svk using revprops for metadata

Pass --use-svm-props or set the svn.usesvmprops key with git-config
to enable using properties set by SVN::Mirror when it mirrored the
upstream URL.

This is heavily based on work from Sam Vilain:
> From: Sam Vilain <sam@vilain.net>
> Date: Sun, 11 Feb 2007 12:34:45 +1300
> Subject: [PATCH] git-svn: re-map repository URLs and UUIDs on SVK mirror paths
>
> If an SVN revision has a property, "svm:headrev", it is likely that
> the revision was created by SVN::Mirror (a part of SVK).  The property
> contains a repository UUID and a revision.  We want to make it look
> like we are mirroring the original URL, so introduce a helper function
> that returns the original identity URL and UUID, and use it when
> generating commit messages.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 git-svn.perl |  115 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 105 insertions(+), 10 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index 7e1a655..23e1d42 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -64,6 +64,7 @@ my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
 		'authors-file|A=s' => \$_authors,
 		'repack:i' => \$Git::SVN::_repack,
 		'no-metadata' => \$Git::SVN::_no_metadata,
+		'use-svm-props|svm-props' => \$Git::SVN::_use_svm_props,
 		'quiet|q' => \$_q,
 		'repack-flags|repack-args|repack-opts=s' =>
 		   \$Git::SVN::_repack_flags,
@@ -645,7 +646,7 @@ package Git::SVN;
 use strict;
 use warnings;
 use vars qw/$default_repo_id $default_ref_id $_no_metadata $_follow_parent
-            $_repack $_repack_flags/;
+            $_repack $_repack_flags $_use_svm_props/;
 use Carp qw/croak/;
 use File::Path qw/mkpath/;
 use File::Copy qw/copy/;
@@ -920,9 +921,54 @@ sub new {
 
 sub refname { "refs/remotes/$_[0]->{ref_id}" }
 
+sub set_svm_vars {
+	my ($self, $ra) = @_;
+	my $section = "svn-remote.$self->{repo_id}";
+
+	# see if we have it in our config, first:
+	eval {
+		$self->{svm} = {
+		  source => $self->tmp_config('--get', "$section.svm-source"),
+		  uuid => $self->tmp_config('--get', "$section.svm-uuid"),
+		}
+	};
+	return $ra if ($self->{svm}->{source} && $self->{svm}->{uuid});
+
+	# nope, make sure we're connected to the repository root:
+	if ($ra->{repos_root} ne $self->{url}) {
+		$ra = Git::SVN::Ra->new($ra->{repos_root});
+	}
+	my $r = $ra->get_latest_revnum;
+	my ($props) = ($ra->get_dir('', $r))[2];
+	if (my $src = $props->{'svm:source'}) {
+		# don't know what a '!' is there for, also the
+		# username is of no interest
+		$src =~ s{!$}{};
+		$src =~ s{(^[a-z\+]*://)[^/@]*@}{$1};
+		$self->tmp_config('--add', "$section.svm-source", $src);
+
+		my $uuid = $props->{'svm:uuid'};
+		$uuid =~ m{^[0-9a-f\-]{30,}$}
+		    or die "doesn't look right - svm:uuid is '$uuid'\n";
+		$self->tmp_config('--add', "$section.svm-uuid", $uuid);
+
+		$self->{svm} = { source => $src , uuid => $uuid };
+	}
+	if ($ra->{repos_root} ne $self->{url}) {
+		$ra = Git::SVN::Ra->new($self->{url});
+	}
+	$ra;
+}
+
 sub ra {
 	my ($self) = shift;
-	Git::SVN::Ra->new($self->{url});
+	my $ra = Git::SVN::Ra->new($self->{url});
+	$self->{-use_svm_props} = $Git::SVN::_use_svm_props;
+	if ($self->{-use_svm_props} && !$self->{svm}) {
+		$ra = $self->set_svm_vars($ra);
+		$self->{-want_revprops} = 1;
+	}
+	$ra;
 }
 
 sub rel_path {
@@ -1006,16 +1052,44 @@ sub get_fetch_range {
 	(++$min, $max);
 }
 
+sub tmp_config {
+	my ($self, @args) = @_;
+	unless (-f $self->{config}) {
+		open my $fh, '>', $self->{config} or
+		    die "Can't open $self->{config}: $!\n";
+		print $fh "; This file is used internally by git-svn\n" or
+		      die "Couldn't write to $self->{config}: $!\n";
+		print $fh "; You should not have to edit it\n" or
+		      die "Couldn't write to $self->{config}: $!\n";
+		close $fh or die "Couldn't close $self->{config}: $!\n";
+	}
+	my $old_config = $ENV{GIT_CONFIG};
+	$ENV{GIT_CONFIG} = $self->{config};
+	$@ = undef;
+	my @ret = eval { command('config', @args) };
+	my $err = $@;
+	if (defined $old_config) {
+		$ENV{GIT_CONFIG} = $old_config;
+	} else {
+		delete $ENV{GIT_CONFIG};
+	}
+	die $err if $err;
+	wantarray ? @ret : $ret[0];
+}
+
 sub tmp_index_do {
 	my ($self, $sub) = @_;
 	my $old_index = $ENV{GIT_INDEX_FILE};
 	$ENV{GIT_INDEX_FILE} = $self->{index};
-	my @ret = &$sub;
-	if ($old_index) {
+	$@ = undef;
+	my @ret = eval { &$sub };
+	my $err = $@;
+	if (defined $old_index) {
 		$ENV{GIT_INDEX_FILE} = $old_index;
 	} else {
 		delete $ENV{GIT_INDEX_FILE};
 	}
+	die $err if $err;
 	wantarray ? @ret : $ret[0];
 }
 
@@ -1105,9 +1179,8 @@ sub do_git_commit {
 	                                                           or croak $!;
 	print $msg_fh $log_entry->{log} or croak $!;
 	unless ($_no_metadata) {
-		print $msg_fh "\ngit-svn-id: ", $self->full_url, '@',
-		              $log_entry->{revision}, ' ',
-		              $self->ra->uuid, "\n" or croak $!;
+		print $msg_fh "\ngit-svn-id: $log_entry->{metadata}\n"
+		              or croak $!;
 	}
 	$msg_fh->flush == 0 or croak $!;
 	close $msg_fh or croak $!;
@@ -1123,7 +1196,11 @@ sub do_git_commit {
 
 	$self->{last_rev} = $log_entry->{revision};
 	$self->{last_commit} = $commit;
-	print "r$log_entry->{revision} = $commit ($self->{ref_id})\n";
+	print "r$log_entry->{revision}";
+	if (defined $log_entry->{svm_revision}) {
+		 print " (\@$log_entry->{svm_revision})";
+	}
+	print " = $commit ($self->{ref_id})\n";
 	if (defined $_repack && (--$_repack_nr == 0)) {
 		$_repack_nr = $_repack;
 		# repack doesn't use any arguments with spaces in them, does it?
@@ -1351,13 +1428,16 @@ sub make_log_entry {
 	my %log_entry = ( parents => $parents || [], revision => $rev,
 	                  log => '');
 
+	my $headrev;
 	my $logged = delete $self->{logged_rev_props};
-	if (!$logged || $self->{-want_extra_revprops}) {
+	if (!$logged || $self->{-want_revprops}) {
 		my $rp = $self->ra->rev_proplist($rev);
 		foreach (sort keys %$rp) {
 			my $v = $rp->{$_};
 			if (/^svn:(author|date|log)$/) {
 				$log_entry{$1} = $v;
+			} elsif ($_ eq 'svm:headrev') {
+				$headrev = $v;
 			} else {
 				print $un "  rev_prop: ", uri_encode($_), ' ',
 					  uri_encode($v), "\n";
@@ -1371,6 +1451,21 @@ sub make_log_entry {
 	$log_entry{date} = parse_svn_date($log_entry{date});
 	$log_entry{author} = check_author($log_entry{author});
 	$log_entry{log} .= "\n";
+	if (defined $headrev && $self->{-use_svm_props}) {
+		my ($uuid, $r) = $headrev =~ m{^([a-f\d\-]{30,}):(\d+)$};
+		if ($uuid ne $self->{svm}->{uuid}) {
+			die "UUID mismatch on SVM path:\n",
+			    "expected: $self->{svm}->{uuid}\n",
+			    "     got: $uuid\n";
+		}
+		my $full_url = $self->{svm}->{source};
+		$full_url .= "/$self->{path}" if length $self->{path};
+		$log_entry{metadata} = "$full_url\@$r $uuid";
+		$log_entry{svm_revision} = $r;
+	} else {
+		$log_entry{metadata} = $self->full_url . "\@$rev " .
+		                       $self->ra->uuid;
+	}
 	\%log_entry;
 }
 
@@ -1549,7 +1644,7 @@ sub _new {
 		close $fh or croak $!;
 	}
 	bless { ref_id => $ref_id, dir => $dir, index => "$dir/index",
-	        path => $path,
+	        path => $path, config => "$ENV{GIT_DIR}/svn/config",
 	        db_path => "$dir/.rev_db", repo_id => $repo_id }, $class;
 }
 
-- 
1.5.0.rc4.104.g9cd7c


-- 
Eric Wong

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] git-svn: re-map repository URLs and UUIDs on SVK mirror paths
  2007-02-11  4:55 ` Eric Wong
@ 2007-02-11  9:41   ` Eric Wong
  0 siblings, 0 replies; 5+ messages in thread
From: Eric Wong @ 2007-02-11  9:41 UTC (permalink / raw)
  To: Sam Vilain; +Cc: git

Eric Wong <normalperson@yhbt.net> wrote:
> Note: these patches (both Sam's and mine below) are not meant for
> master, but the development/semi-rewrite version of git-svn at
> http://git.bogomips.org/git-svn.git
> 
> Sam: here's my take on your patches.  I'll add support for
> per-[svn-remote "..."] configuration that we talked about
> on IRC in a separate patch.

I've added per-[svn-remote "..."] config support to my latest revision.
I forgot to take into account the 'log' command breakage/inconsistency
from using .rev_db with svn-remote.svn.useSvmProps, so the 'git svn log'
command won't work well with -r.  I'll try to find time for that
tomorrow.

-- 
Eric Wong

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] git-svn: re-map repository URLs and UUIDs on SVK mirror paths
  2007-02-10 23:34 [PATCH] git-svn: re-map repository URLs and UUIDs on SVK mirror paths Sam Vilain
  2007-02-11  4:55 ` Eric Wong
@ 2007-02-13 22:21 ` Eric Wong
  2007-02-14  5:18   ` Sam Vilain
  1 sibling, 1 reply; 5+ messages in thread
From: Eric Wong @ 2007-02-13 22:21 UTC (permalink / raw)
  To: Sam Vilain; +Cc: git

Sam Vilain <sam@vilain.net> wrote:
> If an SVN revision has a property, "svm:headrev", it is likely that
> the revision was created by SVN::Mirror (a part of SVK).  The property
> contains a repository UUID and a revision.  We want to make it look
> like we are mirroring the original URL, so introduce a helper function
> that returns the original identity URL and UUID, and use it when
> generating commit messages.

If somebody is using these options with git-svn and wants to dcommit,
they should only be committing to the svm:source repository and not to
the repository managed by SVN::Mirror, right?

-- 
Eric Wong

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] git-svn: re-map repository URLs and UUIDs on SVK mirror paths
  2007-02-13 22:21 ` Eric Wong
@ 2007-02-14  5:18   ` Sam Vilain
  0 siblings, 0 replies; 5+ messages in thread
From: Sam Vilain @ 2007-02-14  5:18 UTC (permalink / raw)
  To: Eric Wong; +Cc: git

Eric Wong wrote:
>> If an SVN revision has a property, "svm:headrev", it is likely that
>> the revision was created by SVN::Mirror (a part of SVK).  The property
>> contains a repository UUID and a revision.  We want to make it look
>> like we are mirroring the original URL, so introduce a helper function
>> that returns the original identity URL and UUID, and use it when
>> generating commit messages.
>>     
> If somebody is using these options with git-svn and wants to dcommit,
> they should only be committing to the svm:source repository and not to
> the repository managed by SVN::Mirror, right?

Yes. Only SVM::Mirror should write to paths below where svm:source and
svm:uuid are seen.

Sam.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-02-14  5:18 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-10 23:34 [PATCH] git-svn: re-map repository URLs and UUIDs on SVK mirror paths Sam Vilain
2007-02-11  4:55 ` Eric Wong
2007-02-11  9:41   ` Eric Wong
2007-02-13 22:21 ` Eric Wong
2007-02-14  5:18   ` Sam Vilain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.