login
Header Space

 
 

[PATCH 2/2] cvsimport: cleanup commit function

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: Martin Langhoff <martin.langhoff@...>, Junio C Hamano <junkio@...>, Matthias Urlichs <smurf@...>, <git@...>
Date: Tuesday, May 23, 2006 - 3:00 am

This change attempts to clean up the commit function to make it a bit
easier to read (or at least the first half of it). It also improves
robustness and performance. Specifically:
  - report get_headref errors on opening ref unless the error is ENOENT
  - use regex to check for sha1 instead of length
  - use lexically scoped filehandles which get cleaned up automagically
  - check for error on both 'print' and 'close' (since output is buffered)
  - avoid "fork, do some perl, then exec" in commit(). It's not necessary,
    and we probably end up COW'ing parts of the perl process. Plus the code
    is much smaller because we can use open2()
  - avoid calling strftime over and over (mainly a readability cleanup)

---

I know this patch is quite large. I can try to split it if you want, but
I suspect it's not worth the effort (either you like refactoring or you
don't :) ).

9dc9f05ab5e1cbd8765238e7b1da0addd6f4296a
 git-cvsimport.perl |  150 ++++++++++++++++++++++------------------------------
 1 files changed, 64 insertions(+), 86 deletions(-)

9dc9f05ab5e1cbd8765238e7b1da0addd6f4296a
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 4efb0a5..f8feb52 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -23,7 +23,7 @@ use File::Basename qw(basename dirname);
 use Time::Local;
 use IO::Socket;
 use IO::Pipe;
-use POSIX qw(strftime dup2);
+use POSIX qw(strftime dup2 :errno_h);
 use IPC::Open2;
 
 $SIG{'PIPE'}="IGNORE";
@@ -429,22 +429,25 @@ sub getwd() {
 	return $pwd;
 }
 
+sub is_sha1 {
+	my $s = shift;
+	return $s =~ /^[a-zA-Z0-9]{40}$/;
+}
 
-sub get_headref($$) {
+sub get_headref ($$) {
     my $name    = shift;
     my $git_dir = shift; 
-    my $sha;
     
-    if (open(C,"$git_dir/refs/heads/$name")) {
-	chomp($sha = <C>);
-	close(C);
-	length($sha) == 40
-	    or die "Cannot get head id for $name ($sha): $!\n";
+    my $f = "$git_dir/refs/heads/$name";
+    if(open(my $fh, $f)) {
+      	    chomp(my $r = <$fh>);
+	    is_sha1($r) or die "Cannot get head id for $name ($r): $!";
+	    return $r;
     }
-    return $sha;
+    die "unable to open $f: $!" unless $! == POSIX::ENOENT;
+    return undef;
 }
 
-
 -d $git_tree
 	or mkdir($git_tree,0777)
 	or die "Could not create $git_tree: $!";
@@ -561,90 +564,67 @@ #---------------------
 
 my $state = 0;
 
-my($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg);
-my(@old,@new,@skipped);
-sub commit {
-	my $pid;
-
+sub update_index (\@\@) {
+	my $old = shift;
+	my $new = shift;
       	open(my $fh, '|-', qw(git-update-index --index-info))
 		or die "unable to open git-update-index: $!";
 	print $fh 
 		(map { "0 0000000000000000000000000000000000000000\t$_\n" }
-			@old),
+			@$old),
 		(map { '100' . sprintf('%o', $_->[0]) . " $_->[1]\t$_->[2]\n" }
-			@new)
+			@$new)
 		or die "unable to write to git-update-index: $!";
 	close $fh
 		or die "unable to write to git-update-index: $!";
 	$? and die "git-update-index reported error: $?";
-	@old = @new = ();
+}
 
-	$pid = open(C,"-|");
-	die "Cannot fork: $!" unless defined $pid;
-	unless($pid) {
-		exec("git-write-tree");
-		die "Cannot exec git-write-tree: $!\n";
-	}
-	chomp(my $tree = <C>);
-	length($tree) == 40
-		or die "Cannot get tree id ($tree): $!\n";
-	close(C)
+sub write_tree () {
+	open(my $fh, '-|', qw(git-write-tree))
+		or die "unable to open git-write-tree: $!";
+	chomp(my $tree = <$fh>);
+	is_sha1($tree)
+		or die "Cannot get tree id ($tree): $!";
+	close($fh)
 		or die "Error running git-write-tree: $?\n";
 	print "Tree ID $tree\n" if $opt_v;
+	return $tree;
+}
 
-	my $parent = "";
-	if(open(C,"$git_dir/refs/heads/$last_branch")) {
-		chomp($parent = <C>);
-		close(C);
-		length($parent) == 40
-			or die "Cannot get parent id ($parent): $!\n";
-		print "Parent ID $parent\n" if $opt_v;
-	}
-
-	my $pr = IO::Pipe->new() or die "Cannot open pipe: $!\n";
-	my $pw = IO::Pipe->new() or die "Cannot open pipe: $!\n";
-	$pid = fork();
-	die "Fork: $!\n" unless defined $pid;
-	unless($pid) {
-		$pr->writer();
-		$pw->reader();
-		open(OUT,">&STDOUT");
-		dup2($pw->fileno(),0);
-		dup2($pr->fileno(),1);
-		$pr->close();
-		$pw->close();
-
-		my @par = ();
-		@par = ("-p",$parent) if $parent;
-
-		# loose detection of merges
-		# based on the commit msg
-		foreach my $rx (@mergerx) {
-			if ($logmsg =~ $rx) {
-				my $mparent = $1;
-				if ($mparent eq 'HEAD') { $mparent = $opt_o };
-				if ( -e "$git_dir/refs/heads/$mparent") {
-					$mparent = get_headref($mparent, $git_dir);
-					push @par, '-p', $mparent;
-					print OUT "Merge parent branch: $mparent\n" if $opt_v;
-				}
-			}
+my($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg);
+my(@old,@new,@skipped);
+sub commit {
+	update_index(@old, @new);
+	@old = @new = ();
+	my $tree = write_tree();
+	my $parent = get_headref($last_branch, $git_dir);
+	print "Parent ID " . ($parent ? $parent : "(empty)") . "\n" if $opt_v;
+
+	my @commit_args;
+	push @commit_args, ("-p", $parent) if $parent;
+
+	# loose detection of merges
+	# based on the commit msg
+	foreach my $rx (@mergerx) {
+		next unless $logmsg =~ $rx && $1;
+		my $mparent = $1 eq 'HEAD' ? $opt_o : $1;
+		if(my $sha1 = get_headref($mparent, $git_dir)) {
+			push @commit_args, '-p', $mparent;
+			print "Merge parent branch: $mparent\n" if $opt_v;
 		}
-
-		exec("env",
-			"GIT_AUTHOR_NAME=$author_name",
-			"GIT_AUTHOR_EMAIL=$author_email",
-			"GIT_AUTHOR_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)),
-			"GIT_COMMITTER_NAME=$author_name",
-			"GIT_COMMITTER_EMAIL=$author_email",
-			"GIT_COMMITTER_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)),
-			"git-commit-tree", $tree,@par);
-		die "Cannot exec git-commit-tree: $!\n";
-
-		close OUT;
 	}
-	$pw->writer();
-	$pr->reader();
+
+	my $commit_date = strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date));
+	my $pid = open2(my $commit_read, my $commit_write,
+		'env',
+		"GIT_AUTHOR_NAME=$author_name",
+		"GIT_AUTHOR_EMAIL=$author_email",
+		"GIT_AUTHOR_DATE=$commit_date",
+		"GIT_COMMITTER_NAME=$author_name",
+		"GIT_COMMITTER_EMAIL=$author_email",
+		"GIT_COMMITTER_DATE=$commit_date",
+		'git-commit-tree', $tree, @commit_args);
 
 	# compatibility with git2cvs
 	substr($logmsg,32767) = "" if length($logmsg) > 32767;
@@ -656,16 +636,14 @@ sub commit {
 	    @skipped = ();
 	}
 
-	print $pw "$logmsg\n"
+	print($commit_write "$logmsg\n") && close($commit_write)
 		or die "Error writing to git-commit-tree: $!\n";
-	$pw->close();
 
-	print "Committed patch $patchset ($branch ".strftime("%Y-%m-%d %H:%M:%S",gmtime($date)).")\n" if $opt_v;
-	chomp(my $cid = <$pr>);
-	length($cid) == 40
-		or die "Cannot get commit id ($cid): $!\n";
+	print "Committed patch $patchset ($branch $commit_date)\n" if $opt_v;
+	chomp(my $cid = <$commit_read>);
+	is_sha1($cid) or die "Cannot get commit id ($cid): $!\n";
 	print "Commit ID $cid\n" if $opt_v;
-	$pr->close();
+	close($commit_read);
 
 	waitpid($pid,0);
 	die "Error running git-commit-tree: $?\n" if $?;
-- 
1.3.3.gcb64-dirty

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
irc usage.., Linus Torvalds, (Sat May 20, 1:26 pm)
Re: irc usage.., Junio C Hamano, (Sat May 20, 1:50 pm)
Re: irc usage.., Yann Dirson, (Sat May 20, 4:39 pm)
Re: irc usage.., Linus Torvalds, (Sun May 21, 9:45 pm)
Re: irc usage.., Donnie Berkholz, (Sat May 20, 6:18 pm)
Re: irc usage.., Linus Torvalds, (Sat May 20, 6:45 pm)
Re: irc usage.., Donnie Berkholz, (Sat May 20, 7:12 pm)
Re: irc usage.., Linus Torvalds, (Sun May 21, 3:24 pm)
Re: irc usage.., Linus Torvalds, (Sun May 21, 11:59 pm)
Re: irc usage.., Donnie Berkholz, (Mon May 22, 12:19 am)
Re: irc usage.., Linus Torvalds, (Mon May 22, 12:50 am)
Re: irc usage.., Martin Langhoff, (Mon May 22, 3:42 am)
Re: irc usage.., Linus Torvalds, (Mon May 22, 5:13 am)
Re: irc usage.., Martin Langhoff, (Mon May 22, 8:54 am)
Re: irc usage.., Linus Torvalds, (Mon May 22, 1:27 pm)
Re: irc usage.., Martin Langhoff, (Mon May 22, 3:46 pm)
Re: irc usage.., Donnie Berkholz, (Mon May 22, 3:09 pm)
Re: irc usage.., Linus Torvalds, (Mon May 22, 3:38 pm)
Re: irc usage.., Donnie Berkholz, (Mon May 22, 3:49 pm)
Re: irc usage.., Linus Torvalds, (Mon May 22, 4:20 pm)
Re: irc usage.., Donnie Berkholz, (Mon May 22, 5:48 pm)
Re: irc usage.., Donnie Berkholz, (Mon May 29, 5:54 pm)
Re: irc usage.., Martin Langhoff, (Mon May 29, 6:21 pm)
Re: irc usage.., Donnie Berkholz, (Mon May 29, 6:32 pm)
Re: irc usage.., Martin Langhoff, (Tue May 30, 6:31 pm)
Re: irc usage.., Linus Torvalds, (Tue May 30, 7:07 pm)
Re: irc usage.., Martin Langhoff, (Tue May 30, 9:04 pm)
Re: irc usage.., Donnie Berkholz, (Tue May 30, 10:49 pm)
Re: irc usage.., Martin Langhoff, (Wed May 31, 2:05 am)
Re: irc usage.., Alec Warner, (Wed May 31, 9:54 am)
Re: irc usage.., Martin Langhoff, (Wed May 31, 6:03 pm)
Re: irc usage.., Alec Warner, (Wed May 31, 9:42 pm)
Re: irc usage.., Martin Langhoff, (Thu Jun 1, 3:47 am)
Re: irc usage.., Alec Warner, (Sun Jun 4, 8:33 pm)
Re: irc usage.., Martin Langhoff, (Sun Jun 4, 10:06 pm)
Re: irc usage.., Alec Warner, (Sun Jun 4, 10:36 pm)
Re: irc usage.., Sean, (Mon Jun 5, 12:07 pm)
Re: irc usage.., Martin Langhoff, (Sun Jun 4, 11:49 pm)
Re: irc usage.., Linus Torvalds, (Mon May 29, 8:43 pm)
Re: irc usage.., Martin Langhoff, (Mon May 29, 8:19 pm)
Re: irc usage.., Donnie Berkholz, (Tue May 30, 1:31 am)
Re: irc usage.., Martin Langhoff, (Tue May 30, 2:01 am)
Re: irc usage.., Martin Langhoff, (Mon May 22, 3:41 pm)
Re: irc usage.., Linus Torvalds, (Mon May 22, 4:11 pm)
Re: irc usage.., Linus Torvalds, (Mon May 22, 4:33 pm)
Re: irc usage.., Matthias Urlichs, (Mon May 22, 5:41 pm)
Re: irc usage.., Linus Torvalds, (Mon May 22, 6:18 pm)
Re: irc usage.., Martin Langhoff, (Mon May 22, 7:23 pm)
Re: irc usage.., Linus Torvalds, (Mon May 22, 7:33 pm)
Re: irc usage.., Martin Langhoff, (Mon May 22, 7:29 pm)
Re: irc usage.., Junio C Hamano, (Mon May 22, 6:39 pm)
Re: irc usage.., Martin Langhoff, (Mon May 22, 7:15 pm)
Re: irc usage.., Jeff King, (Tue May 23, 2:52 am)
[PATCH 2/2] cvsimport: cleanup commit function, Jeff King, (Tue May 23, 3:00 am)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Morten Welinder, (Tue May 23, 1:47 pm)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Jeff King, (Tue May 23, 4:59 pm)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Junio C Hamano, (Tue May 23, 7:41 pm)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Jeff King, (Wed May 24, 5:52 am)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Martin Langhoff, (Tue May 23, 4:13 am)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Linus Torvalds, (Tue May 23, 12:50 pm)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Linus Torvalds, (Tue May 23, 3:36 pm)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Martin Langhoff, (Tue May 23, 4:29 pm)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Jeff King, (Tue May 23, 5:10 pm)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Martin Langhoff, (Tue May 23, 5:13 pm)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Junio C Hamano, (Tue May 23, 4:25 pm)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Junio C Hamano, (Tue May 23, 4:24 am)
Re: [PATCH 2/2] cvsimport: cleanup commit function, Martin Langhoff, (Tue May 23, 4:32 pm)
[PATCH 2/2] cvsimport: cleanup commit function, Jeff King, (Tue May 23, 3:27 am)
Re: irc usage.., Jeff King, (Tue May 23, 2:58 am)
Re: irc usage.., Donnie Berkholz, (Mon May 22, 4:16 pm)
Re: irc usage.., Martin Langhoff, (Mon May 22, 1:04 am)
Re: irc usage.., Donnie Berkholz, (Mon May 22, 1:21 am)
Re: irc usage.., Thomas Glanzmann, (Sun May 21, 5:46 am)
Re: irc usage.., Donnie Berkholz, (Sat May 20, 9:14 pm)
speck-geostationary