git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* contrib/git-svn: polishing up
@ 2006-03-03  9:20 Eric Wong
  2006-03-03  9:20 ` [PATCH 1/9] contrib/git-svn: add -b/--branch switch for branch detection Eric Wong
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Wong @ 2006-03-03  9:20 UTC (permalink / raw)
  To: junkio; +Cc: git


Mostly small things: documentation and code cleanups.

One bugfix of some significance:
    
    Edited commit messages are parsed back to remotes/git-svn
    correctly.  The sequential commit optimization broke this :x

Significant new features:
    
    --branch/-b is interesting and fun for those of you who miss 'real'
    branch support in SVN.

    --authors-file/-A support, because git-svnimport has it :)

None of the core commit/fetch tree-writing code was touched.

 git-svn.perl |  210 ++++++++++++++++++++++++++++++++++++++++-------------------
 git-svn.txt  |   34 ++++++++-
 2 files changed, 176 insertions(+), 68 deletions(-)

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

* [PATCH 1/9] contrib/git-svn: add -b/--branch switch for branch detection
  2006-03-03  9:20 contrib/git-svn: polishing up Eric Wong
@ 2006-03-03  9:20 ` Eric Wong
  2006-03-03  9:20   ` [PATCH 2/9] contrib/git-svn: several small bug fixes and changes Eric Wong
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Wong @ 2006-03-03  9:20 UTC (permalink / raw)
  To: junkio; +Cc: git

I've said I don't like branches in Subversion, and I still don't.
This is a bit more flexible, though, as the argument for -b is any
arbitrary git head/tag reference.

This makes some things easier:
 * Importing git history into a brand new SVN branch.
 * Tracking multiple SVN branches via GIT_SVN_ID, even from multiple
   repositories.
 * Adding tags from SVN (still need to use GIT_SVN_ID, though).
 * Even merge tracking is supported, if and only the heads end up with
   100% equivalent tree objects.  This is more stricter but more robust
   and foolproof than parsing commit messages, imho.

Signed-off-by: Eric Wong <normalperson@yhbt.net>

---

 contrib/git-svn/git-svn.perl |   38 ++++++++++++++++++++++++++++++++++++++
 contrib/git-svn/git-svn.txt  |   17 ++++++++++++++++-
 2 files changed, 54 insertions(+), 1 deletions(-)

536109ffa6682954d3b2bb6a184978fd185ecaa4
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 0e092c5..1f9a470 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -35,6 +35,7 @@ my $sha1 = qr/[a-f\d]{40}/;
 my $sha1_short = qr/[a-f\d]{6,40}/;
 my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,
 	$_find_copies_harder, $_l, $_version, $_upgrade);
+my (@_branch_from, %tree_map);
 
 GetOptions(	'revision|r=s' => \$_revision,
 		'no-ignore-externals' => \$_no_ignore_ext,
@@ -43,6 +44,7 @@ GetOptions(	'revision|r=s' => \$_revisio
 		'rmdir' => \$_rmdir,
 		'upgrade' => \$_upgrade,
 		'help|H|h' => \$_help,
+		'branch|b=s' => \@_branch_from,
 		'find-copies-harder' => \$_find_copies_harder,
 		'l=i' => \$_l,
 		'version|V' => \$_version,
@@ -831,6 +833,8 @@ sub git_commit {
 	my $uuid = $info->{'Repository UUID'};
 	defined $uuid or croak "Unable to get Repository UUID\n";
 
+	map_tree_joins() if (@_branch_from && !%tree_map);
+
 	# commit parents can be conditionally bound to a particular
 	# svn revision via: "svn_revno=commit_sha1", filter them out here:
 	my @exec_parents;
@@ -852,6 +856,17 @@ sub git_commit {
 		git_addremove();
 		chomp(my $tree = `git-write-tree`);
 		croak if $?;
+		if (exists $tree_map{$tree}) {
+			my %seen_parent = map { $_ => 1 } @exec_parents;
+			foreach (@{$tree_map{$tree}}) {
+				# MAXPARENT is defined to 16 in commit-tree.c:
+				if ($seen_parent{$_} || @exec_parents > 16) {
+					next;
+				}
+				push @exec_parents, $_;
+				$seen_parent{$_} = 1;
+			}
+		}
 		my $msg_fh = IO::File->new_tmpfile or croak $!;
 		print $msg_fh $log_msg->{msg}, "\ngit-svn-id: ",
 					"$SVN_URL\@$log_msg->{revision}",
@@ -975,6 +990,29 @@ sub check_upgrade_needed {
 	}
 }
 
+# fills %tree_map with a reverse mapping of trees to commits.  Useful
+# for finding parents to commit on.
+sub map_tree_joins {
+	foreach my $br (@_branch_from) {
+		my $pid = open my $pipe, '-|';
+		defined $pid or croak $!;
+		if ($pid == 0) {
+			exec(qw(git-rev-list --pretty=raw), $br) or croak $?;
+		}
+		while (<$pipe>) {
+			if (/^commit ($sha1)$/o) {
+				my $commit = $1;
+				my ($tree) = (<$pipe> =~ /^tree ($sha1)$/o);
+				unless (defined $tree) {
+					die "Failed to parse commit $commit\n";
+				}
+				push @{$tree_map{$tree}}, $commit;
+			}
+		}
+		close $pipe or croak $?;
+	}
+}
+
 __END__
 
 Data structures:
diff --git a/contrib/git-svn/git-svn.txt b/contrib/git-svn/git-svn.txt
index 4102deb..7306048 100644
--- a/contrib/git-svn/git-svn.txt
+++ b/contrib/git-svn/git-svn.txt
@@ -27,7 +27,7 @@ For importing svn, git-svnimport is pote
 operating on repositories organized under the recommended
 trunk/branch/tags structure, and should be faster, too.
 
-git-svn completely ignores the very limited view of branching that
+git-svn mostly ignores the very limited view of branching that
 Subversion has.  This allows git-svn to be much easier to use,
 especially on repositories that are not organized in a manner that
 git-svnimport is designed for.
@@ -116,6 +116,21 @@ OPTIONS
 	They are both passed directly to git-diff-tree see
 	git-diff-tree(1) for more information.
 
+-b<refname>::
+--branch <refname>::
+	Used with 'fetch' or 'commit'.
+
+	This can be used to join arbitrary git branches to remotes/git-svn
+	on new commits where the tree object is equivalent.
+
+	When used with different GIT_SVN_ID values, tags and branches in
+	SVN can be tracked this way, as can some merges where the heads
+	end up having completely equivalent content.  This can even be
+	used to track branches across multiple SVN _repositories_.
+
+	This option may be specified multiple times, once for each
+	branch.
+
 COMPATIBILITY OPTIONS
 ---------------------
 --no-ignore-externals::
-- 
1.2.3.g4676

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

* [PATCH 2/9] contrib/git-svn: several small bug fixes and changes
  2006-03-03  9:20 ` [PATCH 1/9] contrib/git-svn: add -b/--branch switch for branch detection Eric Wong
@ 2006-03-03  9:20   ` Eric Wong
  2006-03-03  9:20     ` [PATCH 3/9] contrib/git-svn: strip 'git-svn-id:' when commiting to SVN Eric Wong
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Wong @ 2006-03-03  9:20 UTC (permalink / raw)
  To: junkio; +Cc: git

 * Fixed manually-edited commit messages not going to
   remotes/git-svn on sequential commits after the sequential
   commit optimization.
 * format help correctly after adding 'show-ignore'
 * sha1_short regexp matches down to 4 hex characters
   (from git-rev-parse --short documentation)
 * Print the first line of the commit message when we commit to
   SVN next to the sha1.
 * Document 'T' (type change) in the comments

Signed-off-by: Eric Wong <normalperson@yhbt.net>

---

 contrib/git-svn/git-svn.perl |   27 +++++++++++++++++----------
 1 files changed, 17 insertions(+), 10 deletions(-)

43965ace71422148acb1bae488d78cbcfc5ca65e
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 1f9a470..67368a5 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -32,7 +32,7 @@ use Getopt::Long qw/:config gnu_getopt n
 use File::Spec qw//;
 use POSIX qw/strftime/;
 my $sha1 = qr/[a-f\d]{40}/;
-my $sha1_short = qr/[a-f\d]{6,40}/;
+my $sha1_short = qr/[a-f\d]{4,40}/;
 my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,
 	$_find_copies_harder, $_l, $_version, $_upgrade);
 my (@_branch_from, %tree_map);
@@ -90,12 +90,12 @@ Usage: $0 <command> [options] [arguments
 Available commands:
 
 	foreach (sort keys %cmd) {
-		print $fd '  ',pack('A10',$_),$cmd{$_}->[1],"\n";
+		print $fd '  ',pack('A13',$_),$cmd{$_}->[1],"\n";
 	}
 	print $fd <<"";
 \nGIT_SVN_ID may be set in the environment to an arbitrary identifier if
 you're tracking multiple SVN branches/repositories in one git repository
-and want to keep them separate.
+and want to keep them separate.  See git-svn(1) for more information.
 
 	exit $exit;
 }
@@ -245,7 +245,7 @@ sub commit {
 		print "Reading from stdin...\n";
 		@commits = ();
 		while (<STDIN>) {
-			if (/\b([a-f\d]{6,40})\b/) {
+			if (/\b($sha1_short)\b/) {
 				unshift @commits, $1;
 			}
 		}
@@ -267,7 +267,6 @@ sub commit {
 	chdir $SVN_WC or croak $!;
 	my $svn_current_rev =  svn_info('.')->{'Last Changed Rev'};
 	foreach my $c (@revs) {
-		print "Committing $c\n";
 		my $mods = svn_checkout_tree($svn_current_rev, $c);
 		if (scalar @$mods == 0) {
 			print "Skipping, no changes detected\n";
@@ -514,7 +513,7 @@ sub svn_checkout_tree {
 	my ($svn_rev, $treeish) = @_;
 	my $from = file_to_s("$REV_DIR/$svn_rev");
 	assert_svn_wc_clean($svn_rev,$from);
-	print "diff-tree '$from' '$treeish'\n";
+	print "diff-tree $from $treeish\n";
 	my $pid = open my $diff_fh, '-|';
 	defined $pid or croak $!;
 	if ($pid == 0) {
@@ -525,7 +524,7 @@ sub svn_checkout_tree {
 	}
 	my $mods = parse_diff_tree($diff_fh);
 	unless (@$mods) {
-		# git can do empty commits, SVN doesn't allow it...
+		# git can do empty commits, but SVN doesn't allow it...
 		return $mods;
 	}
 	my ($rm, $add) = precommit_check($mods);
@@ -612,7 +611,7 @@ sub svn_commit_tree {
 	my ($svn_rev, $commit) = @_;
 	my $commit_msg = "$GIT_DIR/$GIT_SVN/.svn-commit.tmp.$$";
 	my %log_msg = ( msg => '' );
-	open my $msg, '>', $commit_msg  or croak $!;
+	open my $msg, '>', $commit_msg or croak $!;
 
 	chomp(my $type = `git-cat-file -t $commit`);
 	if ($type eq 'commit') {
@@ -627,7 +626,6 @@ sub svn_commit_tree {
 			if (!$in_msg) {
 				$in_msg = 1 if (/^\s*$/);
 			} else {
-				$log_msg{msg} .= $_;
 				print $msg $_ or croak $!;
 			}
 		}
@@ -639,6 +637,15 @@ sub svn_commit_tree {
 		my $editor = $ENV{VISUAL} || $ENV{EDITOR} || 'vi';
 		system($editor, $commit_msg);
 	}
+
+	# file_to_s removes all trailing newlines, so just use chomp() here:
+	open $msg, '<', $commit_msg or croak $!;
+	{ local $/; chomp($log_msg{msg} = <$msg>); }
+	close $msg or croak $!;
+
+	my ($oneline) = ($log_msg{msg} =~ /([^\n\r]+)/);
+	print "Committing $commit: $oneline\n";
+
 	my @ci_output = safe_qx(qw(svn commit -F),$commit_msg);
 	my ($committed) = grep(/^Committed revision \d+\./,@ci_output);
 	unlink $commit_msg;
@@ -1037,7 +1044,7 @@ diff-index line ($m hash)
 	mode_a => first column of diff-index output, no leading ':',
 	mode_b => second column of diff-index output,
 	sha1_b => sha1sum of the final blob,
-	chg => change type [MCRAD],
+	chg => change type [MCRADT],
 	file_a => original file name of a file (iff chg is 'C' or 'R')
 	file_b => new/current file name of a file (any chg)
 }
-- 
1.2.3.g4676

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

* [PATCH 3/9] contrib/git-svn: strip 'git-svn-id:' when commiting to SVN
  2006-03-03  9:20   ` [PATCH 2/9] contrib/git-svn: several small bug fixes and changes Eric Wong
@ 2006-03-03  9:20     ` Eric Wong
  2006-03-03  9:20       ` [PATCH 4/9] contrib/git-svn: allow --authors-file to be specified Eric Wong
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Wong @ 2006-03-03  9:20 UTC (permalink / raw)
  To: junkio; +Cc: git

We regenerate and use git-svn-id: whenever we fetch or otherwise
commit to remotes/git-svn.  We don't actually know what revision
number we'll commit to SVN at commit time, so this is useless.
It won't throw off things like 'rebuild', though, which knows to
only use the last instance of git-svn-id: in a log message

Signed-off-by: Eric Wong <normalperson@yhbt.net>

---

 contrib/git-svn/git-svn.perl |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

15b28ddfc496fa88cffdfddcc9262cae635a34d0
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 67368a5..edae9d4 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -625,6 +625,9 @@ sub svn_commit_tree {
 		while (<$msg_fh>) {
 			if (!$in_msg) {
 				$in_msg = 1 if (/^\s*$/);
+			} elsif (/^git-svn-id: /) {
+				# skip this, we regenerate the correct one
+				# on re-fetch anyways
 			} else {
 				print $msg $_ or croak $!;
 			}
-- 
1.2.3.g4676

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

* [PATCH 4/9] contrib/git-svn: allow --authors-file to be specified
  2006-03-03  9:20     ` [PATCH 3/9] contrib/git-svn: strip 'git-svn-id:' when commiting to SVN Eric Wong
@ 2006-03-03  9:20       ` Eric Wong
  2006-03-03  9:20         ` [PATCH 5/9] contrib/git-svn: cleanup option parsing Eric Wong
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Wong @ 2006-03-03  9:20 UTC (permalink / raw)
  To: junkio; +Cc: git

Syntax is compatible with git-svnimport and git-cvsimport:

	normalperson = Eric Wong <normalperson@yhbt.net>

If this option is specified and git-svn encounters an SVN
committer name that it cannot parse, it git-svn will abort.

Signed-off-by: Eric Wong <normalperson@yhbt.net>

---

 contrib/git-svn/git-svn.perl |   40 ++++++++++++++++++++++++++++++++--------
 1 files changed, 32 insertions(+), 8 deletions(-)

c501f8378dfb5529993755caaf99ca632418e382
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index edae9d4..c2b4ee9 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -34,8 +34,8 @@ use POSIX qw/strftime/;
 my $sha1 = qr/[a-f\d]{40}/;
 my $sha1_short = qr/[a-f\d]{4,40}/;
 my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,
-	$_find_copies_harder, $_l, $_version, $_upgrade);
-my (@_branch_from, %tree_map);
+	$_find_copies_harder, $_l, $_version, $_upgrade, $_authors);
+my (@_branch_from, %tree_map, %users);
 
 GetOptions(	'revision|r=s' => \$_revision,
 		'no-ignore-externals' => \$_no_ignore_ext,
@@ -46,6 +46,7 @@ GetOptions(	'revision|r=s' => \$_revisio
 		'help|H|h' => \$_help,
 		'branch|b=s' => \@_branch_from,
 		'find-copies-harder' => \$_find_copies_harder,
+		'authors-file|authors|A=s' => \$_authors,
 		'l=i' => \$_l,
 		'version|V' => \$_version,
 		'no-stop-on-copy' => \$_no_stop_copy );
@@ -73,6 +74,19 @@ foreach (keys %cmd) {
 		last;
 	}
 }
+
+# '<svn username> = real-name <email address>' mapping based on git-svnimport:
+if ($_authors) {
+	open my $authors, '<', $_authors or die "Can't open $_authors $!\n";
+	while (<$authors>) {
+		chomp;
+		next unless /^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/;
+		my ($user, $name, $email) = ($1, $2, $3);
+		$users{$user} = [$name, $email];
+	}
+	close $authors or croak $!;
+}
+
 usage(0) if $_help;
 version() if $_version;
 usage(1) unless (defined $cmd);
@@ -740,6 +754,10 @@ sub svn_log_raw {
 					author => $author,
 					lines => $lines,
 					msg => '' );
+			if (defined $_authors && ! defined $users{$author}) {
+				die "Author: $author not defined in ",
+						"$_authors file\n";
+			}
 			push @svn_log, \%log_msg;
 			$state = 'msg_start';
 			next;
@@ -884,12 +902,8 @@ sub git_commit {
 		$msg_fh->flush == 0 or croak $!;
 		seek $msg_fh, 0, 0 or croak $!;
 
-		$ENV{GIT_AUTHOR_NAME} = $ENV{GIT_COMMITTER_NAME} =
-						$log_msg->{author};
-		$ENV{GIT_AUTHOR_EMAIL} = $ENV{GIT_COMMITTER_EMAIL} =
-						$log_msg->{author}."\@$uuid";
-		$ENV{GIT_AUTHOR_DATE} = $ENV{GIT_COMMITTER_DATE} =
-						$log_msg->{date};
+		set_commit_env($log_msg, $uuid);
+
 		my @exec = ('git-commit-tree',$tree);
 		push @exec, '-p', $_  foreach @exec_parents;
 		open STDIN, '<&', $msg_fh or croak $!;
@@ -915,6 +929,16 @@ sub git_commit {
 	return $commit;
 }
 
+sub set_commit_env {
+	my ($log_msg, $uuid) = @_;
+	my $author = $log_msg->{author};
+	my ($name,$email) = defined $users{$author} ?  @{$users{$author}}
+				: ($author,"$author\@$uuid");
+	$ENV{GIT_AUTHOR_NAME} = $ENV{GIT_COMMITTER_NAME} = $name;
+	$ENV{GIT_AUTHOR_EMAIL} = $ENV{GIT_COMMITTER_EMAIL} = $email;
+	$ENV{GIT_AUTHOR_DATE} = $ENV{GIT_COMMITTER_DATE} = $log_msg->{date};
+}
+
 sub apply_mod_line_blob {
 	my $m = shift;
 	if ($m->{mode_b} =~ /^120/) {
-- 
1.2.3.g4676

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

* [PATCH 5/9] contrib/git-svn: cleanup option parsing
  2006-03-03  9:20       ` [PATCH 4/9] contrib/git-svn: allow --authors-file to be specified Eric Wong
@ 2006-03-03  9:20         ` Eric Wong
  2006-03-03  9:20           ` [PATCH 6/9] contrib/git-svn: create a more recent master if one does not exist Eric Wong
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Wong @ 2006-03-03  9:20 UTC (permalink / raw)
  To: junkio; +Cc: git

Signed-off-by: Eric Wong <normalperson@yhbt.net>

---

 contrib/git-svn/git-svn.perl |   65 +++++++++++++++++++++++-------------------
 1 files changed, 35 insertions(+), 30 deletions(-)

a080e189728de9a7aa834b61205df9d8de1025ba
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index c2b4ee9..5d547e8 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -24,6 +24,7 @@ $ENV{LC_ALL} = 'C';
 # If SVN:: library support is added, please make the dependencies
 # optional and preserve the capability to use the command-line client.
 # use eval { require SVN::... } to make it lazy load
+# We don't use any modules not in the standard Perl distribution:
 use Carp qw/croak/;
 use IO::File qw//;
 use File::Basename qw/dirname basename/;
@@ -37,26 +38,25 @@ my ($_revision,$_stdin,$_no_ignore_ext,$
 	$_find_copies_harder, $_l, $_version, $_upgrade, $_authors);
 my (@_branch_from, %tree_map, %users);
 
-GetOptions(	'revision|r=s' => \$_revision,
-		'no-ignore-externals' => \$_no_ignore_ext,
-		'stdin|' => \$_stdin,
-		'edit|e' => \$_edit,
-		'rmdir' => \$_rmdir,
-		'upgrade' => \$_upgrade,
-		'help|H|h' => \$_help,
+my %fc_opts = ( 'no-ignore-externals' => \$_no_ignore_ext,
 		'branch|b=s' => \@_branch_from,
-		'find-copies-harder' => \$_find_copies_harder,
-		'authors-file|authors|A=s' => \$_authors,
-		'l=i' => \$_l,
-		'version|V' => \$_version,
-		'no-stop-on-copy' => \$_no_stop_copy );
+		'authors-file|A=s' => \$_authors );
 my %cmd = (
-	fetch => [ \&fetch, "Download new revisions from SVN" ],
-	init => [ \&init, "Initialize and fetch (import)"],
-	commit => [ \&commit, "Commit git revisions to SVN" ],
-	'show-ignore' => [ \&show_ignore, "Show svn:ignore listings" ],
-	rebuild => [ \&rebuild, "Rebuild git-svn metadata (after git clone)" ],
-	help => [ \&usage, "Show help" ],
+	fetch => [ \&fetch, "Download new revisions from SVN",
+			{ 'revision|r=s' => \$_revision, %fc_opts } ],
+	init => [ \&init, "Initialize and fetch (import)", { } ],
+	commit => [ \&commit, "Commit git revisions to SVN",
+			{	'stdin|' => \$_stdin,
+				'edit|e' => \$_edit,
+				'rmdir' => \$_rmdir,
+				'find-copies-harder' => \$_find_copies_harder,
+				'l=i' => \$_l,
+				%fc_opts,
+			} ],
+	'show-ignore' => [ \&show_ignore, "Show svn:ignore listings", { } ],
+	rebuild => [ \&rebuild, "Rebuild git-svn metadata (after git clone)",
+			{ 'no-ignore-externals' => \$_no_ignore_ext,
+			  'upgrade' => \$_upgrade } ],
 );
 my $cmd;
 for (my $i = 0; $i < @ARGV; $i++) {
@@ -75,21 +75,14 @@ foreach (keys %cmd) {
 	}
 }
 
-# '<svn username> = real-name <email address>' mapping based on git-svnimport:
-if ($_authors) {
-	open my $authors, '<', $_authors or die "Can't open $_authors $!\n";
-	while (<$authors>) {
-		chomp;
-		next unless /^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/;
-		my ($user, $name, $email) = ($1, $2, $3);
-		$users{$user} = [$name, $email];
-	}
-	close $authors or croak $!;
-}
+my %opts;
+%opts = %{$cmd{$cmd}->[2]} if (defined $cmd);
 
+GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version ) or exit 1;
 usage(0) if $_help;
 version() if $_version;
-usage(1) unless (defined $cmd);
+usage(1) unless defined $cmd;
+load_authors() if $_authors;
 svn_check_ignore_externals();
 $cmd{$cmd}->[0]->(@ARGV);
 exit 0;
@@ -1047,6 +1040,18 @@ sub map_tree_joins {
 	}
 }
 
+# '<svn username> = real-name <email address>' mapping based on git-svnimport:
+sub load_authors {
+	open my $authors, '<', $_authors or die "Can't open $_authors $!\n";
+	while (<$authors>) {
+		chomp;
+		next unless /^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/;
+		my ($user, $name, $email) = ($1, $2, $3);
+		$users{$user} = [$name, $email];
+	}
+	close $authors or croak $!;
+}
+
 __END__
 
 Data structures:
-- 
1.2.3.g4676

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

* [PATCH 8/9] contrib/git-svn: add --id/-i=$GIT_SVN_ID command-line switch
  2006-03-03  9:20             ` [PATCH 7/9] contrib/git-svn: avoid re-reading the repository uuid, it never changes Eric Wong
@ 2006-03-03  9:20               ` Eric Wong
  2006-03-03  9:20                 ` [PATCH 9/9] contrib/git-svn: better documenting of CLI switches Eric Wong
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Wong @ 2006-03-03  9:20 UTC (permalink / raw)
  To: junkio; +Cc: git

I ended up using GIT_SVN_ID far more than I ever thought I
would.  Typing less is good.

Signed-off-by: Eric Wong <normalperson@yhbt.net>

---

 contrib/git-svn/git-svn.perl |   19 +++++++++++--------
 1 files changed, 11 insertions(+), 8 deletions(-)

1d3dc63f7ed276863c71f9a212471658f359ef75
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 041791b..db199a3 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -10,13 +10,6 @@ use vars qw/	$AUTHOR $VERSION
 $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
 $VERSION = '0.10.0';
 $GIT_DIR = $ENV{GIT_DIR} || "$ENV{PWD}/.git";
-$GIT_SVN = $ENV{GIT_SVN_ID} || 'git-svn';
-$GIT_SVN_INDEX = "$GIT_DIR/$GIT_SVN/index";
-$ENV{GIT_DIR} ||= $GIT_DIR;
-$SVN_URL = undef;
-$REV_DIR = "$GIT_DIR/$GIT_SVN/revs";
-$SVN_WC = "$GIT_DIR/$GIT_SVN/tree";
-
 # make sure the svn binary gives consistent output between locales and TZs:
 $ENV{TZ} = 'UTC';
 $ENV{LC_ALL} = 'C';
@@ -78,7 +71,17 @@ foreach (keys %cmd) {
 my %opts;
 %opts = %{$cmd{$cmd}->[2]} if (defined $cmd);
 
-GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version ) or exit 1;
+GetOptions(%opts, 'help|H|h' => \$_help,
+		'version|V' => \$_version,
+		'id|i=s' => \$GIT_SVN) or exit 1;
+
+$GIT_SVN ||= $ENV{GIT_SVN_ID} || 'git-svn';
+$GIT_SVN_INDEX = "$GIT_DIR/$GIT_SVN/index";
+$ENV{GIT_DIR} ||= $GIT_DIR;
+$SVN_URL = undef;
+$REV_DIR = "$GIT_DIR/$GIT_SVN/revs";
+$SVN_WC = "$GIT_DIR/$GIT_SVN/tree";
+
 usage(0) if $_help;
 version() if $_version;
 usage(1) unless defined $cmd;
-- 
1.2.3.g4676

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

* [PATCH 9/9] contrib/git-svn: better documenting of CLI switches
  2006-03-03  9:20               ` [PATCH 8/9] contrib/git-svn: add --id/-i=$GIT_SVN_ID command-line switch Eric Wong
@ 2006-03-03  9:20                 ` Eric Wong
  0 siblings, 0 replies; 10+ messages in thread
From: Eric Wong @ 2006-03-03  9:20 UTC (permalink / raw)
  To: junkio; +Cc: git

Also, fix a asciidoc formatting error

Signed-off-by: Eric Wong <normalperson@yhbt.net>

---

 contrib/git-svn/git-svn.perl |   29 +++++++++++++++--------------
 contrib/git-svn/git-svn.txt  |   17 ++++++++++++++++-
 2 files changed, 31 insertions(+), 15 deletions(-)

65d8e4920084c96f82b4604ded1bd4e4fa91d3d8
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index db199a3..808b933 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -60,16 +60,7 @@ for (my $i = 0; $i < @ARGV; $i++) {
 	}
 };
 
-# we may be called as git-svn-(command), or git-svn(command).
-foreach (keys %cmd) {
-	if (/git\-svn\-?($_)(?:\.\w+)?$/) {
-		$cmd = $1;
-		last;
-	}
-}
-
-my %opts;
-%opts = %{$cmd{$cmd}->[2]} if (defined $cmd);
+my %opts = %{$cmd{$cmd}->[2]} if (defined $cmd);
 
 GetOptions(%opts, 'help|H|h' => \$_help,
 		'version|V' => \$_version,
@@ -97,15 +88,25 @@ sub usage {
 	print $fd <<"";
 git-svn - bidirectional operations between a single Subversion tree and git
 Usage: $0 <command> [options] [arguments]\n
-Available commands:
+
+	print $fd "Available commands:\n" unless $cmd;
 
 	foreach (sort keys %cmd) {
+		next if $cmd && $cmd ne $_;
 		print $fd '  ',pack('A13',$_),$cmd{$_}->[1],"\n";
+		foreach (keys %{$cmd{$_}->[2]}) {
+			# prints out arguments as they should be passed:
+			my $x = s#=s$## ? '<arg>' : s#=i$## ? '<num>' : '';
+			print $fd ' ' x 17, join(', ', map { length $_ > 1 ?
+							"--$_" : "-$_" }
+						split /\|/,$_)," $x\n";
+		}
 	}
 	print $fd <<"";
-\nGIT_SVN_ID may be set in the environment to an arbitrary identifier if
-you're tracking multiple SVN branches/repositories in one git repository
-and want to keep them separate.  See git-svn(1) for more information.
+\nGIT_SVN_ID may be set in the environment or via the --id/-i switch to an
+arbitrary identifier if you're tracking multiple SVN branches/repositories in
+one git repository and want to keep them separate.  See git-svn(1) for more
+information.
 
 	exit $exit;
 }
diff --git a/contrib/git-svn/git-svn.txt b/contrib/git-svn/git-svn.txt
index 7306048..8e9a971 100644
--- a/contrib/git-svn/git-svn.txt
+++ b/contrib/git-svn/git-svn.txt
@@ -116,6 +116,8 @@ OPTIONS
 	They are both passed directly to git-diff-tree see
 	git-diff-tree(1) for more information.
 
+ADVANCED OPTIONS
+----------------
 -b<refname>::
 --branch <refname>::
 	Used with 'fetch' or 'commit'.
@@ -131,8 +133,21 @@ OPTIONS
 	This option may be specified multiple times, once for each
 	branch.
 
+-i<GIT_SVN_ID>::
+--id <GIT_SVN_ID>::
+	This sets GIT_SVN_ID (instead of using the environment).  See
+	the section on "Tracking Multiple Repositories or Branches" for
+	more information on using GIT_SVN_ID.
+
 COMPATIBILITY OPTIONS
 ---------------------
+--upgrade::
+	Only used with the 'rebuild' command.
+
+	Run this if you used an old version of git-svn that used
+	'git-svn-HEAD' instead of 'remotes/git-svn' as the branch
+	for tracking the remote.
+
 --no-ignore-externals::
 	Only used with the 'fetch' and 'rebuild' command.
 
@@ -177,7 +192,7 @@ Tracking and contributing to an Subversi
 	git-svn commit remotes/git-svn..my-branch
 # Something is committed to SVN, pull the latest into your branch::
 	git-svn fetch && git pull . remotes/git-svn
-# Append svn:ignore settings to the default git exclude file:
+# Append svn:ignore settings to the default git exclude file::
 	git-svn show-ignore >> .git/info/exclude
 
 DESIGN PHILOSOPHY
-- 
1.2.3.g4676

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

* [PATCH 6/9] contrib/git-svn: create a more recent master if one does not exist
  2006-03-03  9:20         ` [PATCH 5/9] contrib/git-svn: cleanup option parsing Eric Wong
@ 2006-03-03  9:20           ` Eric Wong
  2006-03-03  9:20             ` [PATCH 7/9] contrib/git-svn: avoid re-reading the repository uuid, it never changes Eric Wong
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Wong @ 2006-03-03  9:20 UTC (permalink / raw)
  To: junkio; +Cc: git

In a new repository, the initial fetch creates a master branch
if one does not exist so HEAD has something to point to.

It now creates a master at the end of the initial fetch run,
pointing to the latest revision.  Previously it pointed to the
first revision imported, which is generally less useful.

Signed-off-by: Eric Wong <normalperson@yhbt.net>

---

 contrib/git-svn/git-svn.perl |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

7d3cf853ffbe0d1ce8a15fa5ac3dad793ddb5021
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 5d547e8..69b6be3 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -224,9 +224,6 @@ sub fetch {
 		sys(@svn_co, $SVN_URL, $SVN_WC);
 		chdir $SVN_WC or croak $!;
 		$last_commit = git_commit($base, @parents);
-		unless (-f "$GIT_DIR/refs/heads/master") {
-			sys(qw(git-update-ref refs/heads/master),$last_commit);
-		}
 		assert_svn_wc_clean($base->{revision}, $last_commit);
 	} else {
 		chdir $SVN_WC or croak $!;
@@ -242,6 +239,9 @@ sub fetch {
 		$last_commit = git_commit($log_msg, $last_commit, @parents);
 	}
 	assert_svn_wc_clean($last_rev, $last_commit);
+	unless (-e "$GIT_DIR/refs/heads/master") {
+		sys(qw(git-update-ref refs/heads/master),$last_commit);
+	}
 	return pop @$svn_log;
 }
 
-- 
1.2.3.g4676

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

* [PATCH 7/9] contrib/git-svn: avoid re-reading the repository uuid, it never changes
  2006-03-03  9:20           ` [PATCH 6/9] contrib/git-svn: create a more recent master if one does not exist Eric Wong
@ 2006-03-03  9:20             ` Eric Wong
  2006-03-03  9:20               ` [PATCH 8/9] contrib/git-svn: add --id/-i=$GIT_SVN_ID command-line switch Eric Wong
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Wong @ 2006-03-03  9:20 UTC (permalink / raw)
  To: junkio; +Cc: git

If it does change, we're screwed anyways as SVN will refuse to
commit or update.  We also never access more than one SVN
repository per-invocation, so we can store it as a global, too.

Signed-off-by: Eric Wong <normalperson@yhbt.net>

---

 contrib/git-svn/git-svn.perl |   27 ++++++++++++---------------
 1 files changed, 12 insertions(+), 15 deletions(-)

3dc689059bd5cffa12bb2b8cdc0f1965d5f6cee2
diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 69b6be3..041791b 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -4,7 +4,7 @@
 use warnings;
 use strict;
 use vars qw/	$AUTHOR $VERSION
-		$SVN_URL $SVN_INFO $SVN_WC
+		$SVN_URL $SVN_INFO $SVN_WC $SVN_UUID
 		$GIT_SVN_INDEX $GIT_SVN
 		$GIT_DIR $REV_DIR/;
 $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
@@ -114,7 +114,6 @@ sub version {
 
 sub rebuild {
 	$SVN_URL = shift or undef;
-	my $repo_uuid;
 	my $newest_rev = 0;
 	if ($_upgrade) {
 		sys('git-update-ref',"refs/remotes/$GIT_SVN","$GIT_SVN-HEAD");
@@ -150,7 +149,7 @@ sub rebuild {
 
 		# if we merged or otherwise started elsewhere, this is
 		# how we break out of it
-		next if (defined $repo_uuid && ($uuid ne $repo_uuid));
+		next if (defined $SVN_UUID && ($uuid ne $SVN_UUID));
 		next if (defined $SVN_URL && ($url ne $SVN_URL));
 
 		print "r$rev = $c\n";
@@ -159,7 +158,7 @@ sub rebuild {
 				croak "SVN repository location required: $url\n";
 			}
 			$SVN_URL ||= $url;
-			$repo_uuid ||= setup_git_svn();
+			$SVN_UUID ||= setup_git_svn();
 			$latest = $rev;
 		}
 		assert_revision_eq_or_unknown($rev, $c);
@@ -252,7 +251,7 @@ sub commit {
 		print "Reading from stdin...\n";
 		@commits = ();
 		while (<STDIN>) {
-			if (/\b($sha1_short)\b/) {
+			if (/\b($sha1_short)\b/o) {
 				unshift @commits, $1;
 			}
 		}
@@ -320,14 +319,14 @@ sub setup_git_svn {
 	mkpath(["$GIT_DIR/$GIT_SVN/info"]);
 	mkpath([$REV_DIR]);
 	s_to_file($SVN_URL,"$GIT_DIR/$GIT_SVN/info/url");
-	my $uuid = svn_info($SVN_URL)->{'Repository UUID'} or
+	$SVN_UUID = svn_info($SVN_URL)->{'Repository UUID'} or
 					croak "Repository UUID unreadable\n";
-	s_to_file($uuid,"$GIT_DIR/$GIT_SVN/info/uuid");
+	s_to_file($SVN_UUID,"$GIT_DIR/$GIT_SVN/info/uuid");
 
 	open my $fd, '>>', "$GIT_DIR/$GIT_SVN/info/exclude" or croak $!;
 	print $fd '.svn',"\n";
 	close $fd or croak $!;
-	return $uuid;
+	return $SVN_UUID;
 }
 
 sub assert_svn_wc_clean {
@@ -850,9 +849,7 @@ sub git_commit {
 	my ($log_msg, @parents) = @_;
 	assert_revision_unknown($log_msg->{revision});
 	my $out_fh = IO::File->new_tmpfile or croak $!;
-	my $info = svn_info('.');
-	my $uuid = $info->{'Repository UUID'};
-	defined $uuid or croak "Unable to get Repository UUID\n";
+	$SVN_UUID ||= svn_info('.')->{'Repository UUID'};
 
 	map_tree_joins() if (@_branch_from && !%tree_map);
 
@@ -891,11 +888,11 @@ sub git_commit {
 		my $msg_fh = IO::File->new_tmpfile or croak $!;
 		print $msg_fh $log_msg->{msg}, "\ngit-svn-id: ",
 					"$SVN_URL\@$log_msg->{revision}",
-					" $uuid\n" or croak $!;
+					" $SVN_UUID\n" or croak $!;
 		$msg_fh->flush == 0 or croak $!;
 		seek $msg_fh, 0, 0 or croak $!;
 
-		set_commit_env($log_msg, $uuid);
+		set_commit_env($log_msg);
 
 		my @exec = ('git-commit-tree',$tree);
 		push @exec, '-p', $_  foreach @exec_parents;
@@ -923,10 +920,10 @@ sub git_commit {
 }
 
 sub set_commit_env {
-	my ($log_msg, $uuid) = @_;
+	my ($log_msg) = @_;
 	my $author = $log_msg->{author};
 	my ($name,$email) = defined $users{$author} ?  @{$users{$author}}
-				: ($author,"$author\@$uuid");
+				: ($author,"$author\@$SVN_UUID");
 	$ENV{GIT_AUTHOR_NAME} = $ENV{GIT_COMMITTER_NAME} = $name;
 	$ENV{GIT_AUTHOR_EMAIL} = $ENV{GIT_COMMITTER_EMAIL} = $email;
 	$ENV{GIT_AUTHOR_DATE} = $ENV{GIT_COMMITTER_DATE} = $log_msg->{date};
-- 
1.2.3.g4676

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

end of thread, other threads:[~2006-03-03  9:20 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-03  9:20 contrib/git-svn: polishing up Eric Wong
2006-03-03  9:20 ` [PATCH 1/9] contrib/git-svn: add -b/--branch switch for branch detection Eric Wong
2006-03-03  9:20   ` [PATCH 2/9] contrib/git-svn: several small bug fixes and changes Eric Wong
2006-03-03  9:20     ` [PATCH 3/9] contrib/git-svn: strip 'git-svn-id:' when commiting to SVN Eric Wong
2006-03-03  9:20       ` [PATCH 4/9] contrib/git-svn: allow --authors-file to be specified Eric Wong
2006-03-03  9:20         ` [PATCH 5/9] contrib/git-svn: cleanup option parsing Eric Wong
2006-03-03  9:20           ` [PATCH 6/9] contrib/git-svn: create a more recent master if one does not exist Eric Wong
2006-03-03  9:20             ` [PATCH 7/9] contrib/git-svn: avoid re-reading the repository uuid, it never changes Eric Wong
2006-03-03  9:20               ` [PATCH 8/9] contrib/git-svn: add --id/-i=$GIT_SVN_ID command-line switch Eric Wong
2006-03-03  9:20                 ` [PATCH 9/9] contrib/git-svn: better documenting of CLI switches Eric Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).