# [PATCH 3/9] contrib/git-svn: strip 'git-svn-id:' when commiting to SVN

3 messages from 2006-03-03 to 2006-03-03. Participants: Eric Wong.
Thread: https://gitlist.dev/t/3534

## Eric Wong, 2006-03-03 09:20

Subject: [PATCH 2/9] contrib/git-svn: several small bug fixes and changes
Message-ID: <114137760733-git-send-email-normalperson@yhbt.net>
URL: https://gitlist.dev/e/114137760733-git-send-email-normalperson%40yhbt.net
In-Reply-To: <11413776074148-git-send-email-normalperson@yhbt.net>

```
 * 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

```

## Eric Wong, 2006-03-03 09:20

Subject: [PATCH 3/9] contrib/git-svn: strip 'git-svn-id:' when commiting to SVN
Message-ID: <11413776082010-git-send-email-normalperson@yhbt.net>
URL: https://gitlist.dev/e/11413776082010-git-send-email-normalperson%40yhbt.net
In-Reply-To: <114137760733-git-send-email-normalperson@yhbt.net>

```
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

```

## Eric Wong, 2006-03-03 09:20

Subject: [PATCH 4/9] contrib/git-svn: allow --authors-file to be specified
Message-ID: <11413776082506-git-send-email-normalperson@yhbt.net>
URL: https://gitlist.dev/e/11413776082506-git-send-email-normalperson%40yhbt.net
In-Reply-To: <11413776082010-git-send-email-normalperson@yhbt.net>

```
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

```
