git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] git-svn: avoid creating some small files
@ 2006-06-15 20:55 Eric Wong
  2006-06-15 20:55 ` [PATCH 2/3] git-svn: fix several small bugs, enable branch optimization Eric Wong
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Wong @ 2006-06-15 20:55 UTC (permalink / raw)
  To: Junio C Hamano, git; +Cc: Eric Wong

repo_path_split() is already pretty fast, and is already
optimized via caching.

We also don't need to create an exclude file if we're
relying on the SVN libraries.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 contrib/git-svn/git-svn.perl |   26 ++++++++------------------
 1 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 884969e..88af9c5 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -1005,12 +1005,6 @@ sub setup_git_svn {
 	close $fh;
 	s_to_file($SVN_URL,"$GIT_SVN_DIR/info/url");
 
-	open my $fd, '>>', "$GIT_SVN_DIR/info/exclude" or croak $!;
-	print $fd '.svn',"\n";
-	close $fd or croak $!;
-	my ($url, $path) = repo_path_split($SVN_URL);
-	s_to_file($url, "$GIT_SVN_DIR/info/repo_url");
-	s_to_file($path, "$GIT_SVN_DIR/info/repo_path");
 }
 
 sub assert_svn_wc_clean {
@@ -1649,6 +1643,12 @@ sub do_update_index {
 
 sub index_changes {
 	return if $_use_lib;
+
+	if (!-f "$GIT_SVN_DIR/info/exclude") {
+		open my $fd, '>>', "$GIT_SVN_DIR/info/exclude" or croak $!;
+		print $fd '.svn',"\n";
+		close $fd or croak $!;
+	}
 	my $no_text_base = shift;
 	do_update_index([qw/git-diff-files --name-only -z/],
 			'remove',
@@ -2018,9 +2018,6 @@ sub migration_check {
 		my $dn = dirname("$GIT_DIR/svn/$x");
 		mkpath([$dn]) unless -d $dn;
 		rename "$GIT_DIR/$x", "$GIT_DIR/svn/$x" or croak "$!: $x";
-		my ($url, $path) = repo_path_split($u);
-		s_to_file($url, "$GIT_DIR/svn/$x/info/repo_url");
-		s_to_file($path, "$GIT_DIR/svn/$x/info/repo_path");
 	}
 	migrate_revdb() if (-d $GIT_SVN_DIR && !-w $REVDB);
 	print "Done upgrading.\n";
@@ -2138,15 +2135,8 @@ sub write_grafts {
 sub read_url_paths {
 	my $l_map = {};
 	git_svn_each(sub { my $x = shift;
-			my $u = file_to_s("$GIT_DIR/svn/$x/info/repo_url");
-			my $p = file_to_s("$GIT_DIR/svn/$x/info/repo_path");
-			# we hate trailing slashes
-			if ($u =~ s#(?:^\/+|\/+$)##g) {
-				s_to_file($u,"$GIT_DIR/svn/$x/info/repo_url");
-			}
-			if ($p =~ s#(?:^\/+|\/+$)##g) {
-				s_to_file($p,"$GIT_DIR/svn/$x/info/repo_path");
-			}
+			my $url = file_to_s("$GIT_DIR/svn/$x/info/url");
+			my ($u, $p) = repo_path_split($url);
 			$l_map->{$u}->{$p} = $x;
 			});
 	return $l_map;
-- 
1.4.0

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

* [PATCH 2/3] git-svn: fix several small bugs, enable branch optimization
  2006-06-15 20:55 [PATCH 1/3] git-svn: avoid creating some small files Eric Wong
@ 2006-06-15 20:55 ` Eric Wong
  2006-06-15 20:55   ` [PATCH 3/3] git-svn: Eliminate temp file usage in libsvn_get_file() Eric Wong
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Wong @ 2006-06-15 20:55 UTC (permalink / raw)
  To: Junio C Hamano, git; +Cc: Eric Wong

Share the repack counter between branches when doing
multi-fetch.

Pass the -d flag to git repack by default.  That's the
main reason we will want automatic pack generation, to
save space and improve disk cache performance.  I won't
add -a by default since it can generate extremely large
packs that make RAM-starved systems unhappy.

We no longer generate the .git/svn/$GIT_SVN_ID/info/uuid
file, either.  It was never read in the first place.

Check for and create .rev_db if we need to during fetch (in case
somebody manually blew away their .rev_db and wanted to start
over.  Mainly makes debugging easier).

Croak with $? instead of $! if there's an error closing pipes

Quiet down some of the chatter, too.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 contrib/git-svn/git-svn.perl |  146 +++++++++++++++++++++++-------------------
 1 files changed, 81 insertions(+), 65 deletions(-)

diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 88af9c5..27f1d68 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -368,7 +368,6 @@ sub fetch_lib {
 		defined(my $pid = fork) or croak $!;
 		if (!$pid) {
 			$SVN::Error::handler = \&libsvn_skip_unknown_revs;
-			print "Fetching revisions $min .. $max\n";
 
 			# Yes I'm perfectly aware that the fourth argument
 			# below is the limit revisions number.  Unfortunately
@@ -391,7 +390,6 @@ sub fetch_lib {
 							$log_msg, @parents);
 					}
 				});
-			$SVN::Error::handler = sub { 'quiet warnings' };
 			exit 0;
 		}
 		waitpid $pid, 0;
@@ -463,7 +461,7 @@ sub commit_lib {
 	my (@revs) = @_;
 	my ($r_last, $cmt_last) = svn_grab_base_rev();
 	defined $r_last or die "Must have an existing revision to commit\n";
-	my $fetched = fetch_lib();
+	my $fetched = fetch();
 	if ($r_last != $fetched->{revision}) {
 		print STDERR "There are new revisions that were fetched ",
 				"and need to be merged (or acknowledged) ",
@@ -523,7 +521,7 @@ sub commit_lib {
 				$no = 1;
 			}
 		}
-		close $fh or croak $!;
+		close $fh or croak $?;
 		if (! defined $r_new && ! defined $cmt_new) {
 			unless ($no) {
 				die "Failed to parse revision information\n";
@@ -633,17 +631,8 @@ sub multi_init {
 sub multi_fetch {
 	# try to do trunk first, since branches/tags
 	# may be descended from it.
-	if (-d "$GIT_DIR/svn/trunk") {
-		print "Fetching trunk\n";
-		defined(my $pid = fork) or croak $!;
-		if (!$pid) {
-			$GIT_SVN = $ENV{GIT_SVN_ID} = 'trunk';
-			init_vars();
-			fetch(@_);
-			exit 0;
-		}
-		waitpid $pid, 0;
-		croak $? if $?;
+	if (-e "$GIT_DIR/svn/trunk/info/url") {
+		fetch_child_id('trunk', @_);
 	}
 	rec_fetch('', "$GIT_DIR/svn", @_);
 }
@@ -725,6 +714,41 @@ out:
 
 ########################### utility functions #########################
 
+sub fetch_child_id {
+	my $id = shift;
+	print "Fetching $id\n";
+	my $ref = "$GIT_DIR/refs/remotes/$id";
+	my $ca = file_to_s($ref) if (-r $ref);
+	defined(my $pid = fork) or croak $!;
+	if (!$pid) {
+		$GIT_SVN = $ENV{GIT_SVN_ID} = $id;
+		init_vars();
+		fetch(@_);
+		exit 0;
+	}
+	waitpid $pid, 0;
+	croak $? if $?;
+	return unless $_repack || -r $ref;
+
+	my $cb = file_to_s($ref);
+
+	defined($pid = open my $fh, '-|') or croak $!;
+	my $url = file_to_s("$GIT_DIR/svn/$id/info/url");
+	$url = qr/\Q$url\E/;
+	if (!$pid) {
+		exec qw/git-rev-list --pretty=raw/,
+				$ca ? "$ca..$cb" : $cb or croak $!;
+	}
+	while (<$fh>) {
+		if (/^    git-svn-id: $url\@\d+ [a-f0-9\-]+$/) {
+			check_repack();
+		} elsif (/^    git-svn-id: \S+\@\d+ [a-f0-9\-]+$/) {
+			last;
+		}
+	}
+	close $fh;
+}
+
 sub rec_fetch {
 	my ($pfx, $p, @args) = @_;
 	my @dir;
@@ -733,16 +757,7 @@ sub rec_fetch {
 			$pfx .= '/' if $pfx && $pfx !~ m!/$!;
 			my $id = $pfx . basename $_;
 			next if $id eq 'trunk';
-			print "Fetching $id\n";
-			defined(my $pid = fork) or croak $!;
-			if (!$pid) {
-				$GIT_SVN = $ENV{GIT_SVN_ID} = $id;
-				init_vars();
-				fetch(@args);
-				exit 0;
-			}
-			waitpid $pid, 0;
-			croak $? if $?;
+			fetch_child_id($id, @args);
 		} elsif (-d $_) {
 			push @dir, $_;
 		}
@@ -943,7 +958,6 @@ sub read_uuid {
 		$SVN_UUID = $info->{'Repository UUID'} or
 					croak "Repository UUID unreadable\n";
 	}
-	s_to_file($SVN_UUID,"$GIT_SVN_DIR/info/uuid");
 }
 
 sub quiet_run {
@@ -1107,7 +1121,7 @@ sub parse_diff_tree {
 			croak "Error parsing $_\n";
 		}
 	}
-	close $diff_fh or croak $!;
+	close $diff_fh or croak $?;
 
 	return \@mods;
 }
@@ -1348,7 +1362,7 @@ sub get_commit_message {
 				print $msg $_ or croak $!;
 			}
 		}
-		close $msg_fh or croak $!;
+		close $msg_fh or croak $?;
 	}
 	close $msg or croak $!;
 
@@ -1562,7 +1576,7 @@ sub svn_info {
 			push @{$ret->{-order}}, $1;
 		}
 	}
-	close $info_fh or croak $!;
+	close $info_fh or croak $?;
 	return $ret;
 }
 
@@ -1638,7 +1652,7 @@ sub do_update_index {
 		}
 		print $ui $x,"\0";
 	}
-	close $ui or croak $!;
+	close $ui or croak $?;
 }
 
 sub index_changes {
@@ -1765,11 +1779,15 @@ sub git_commit {
 
 	# this output is read via pipe, do not change:
 	print "r$log_msg->{revision} = $commit\n";
+	check_repack();
+	return $commit;
+}
+
+sub check_repack {
 	if ($_repack && (--$_repack_nr == 0)) {
 		$_repack_nr = $_repack;
 		sys("git repack $_repack_flags");
 	}
-	return $commit;
 }
 
 sub set_commit_env {
@@ -1877,6 +1895,10 @@ sub svn_cmd_checkout {
 }
 
 sub check_upgrade_needed {
+	if (!-r $REVDB) {
+		open my $fh, '>>',$REVDB or croak $!;
+		close $fh;
+	}
 	my $old = eval {
 		my $pid = open my $child, '-|';
 		defined $pid or croak $!;
@@ -2026,7 +2048,8 @@ sub migration_check {
 sub find_rev_before {
 	my ($r, $id, $eq_ok) = @_;
 	my $f = "$GIT_DIR/svn/$id/.rev_db";
-	# --$r unless $eq_ok;
+	return (undef,undef) unless -r $f;
+	--$r unless $eq_ok;
 	while ($r > 0) {
 		if (my $c = revdb_get($f, $r)) {
 			return ($r, $c);
@@ -2072,7 +2095,7 @@ sub set_default_vals {
 	if (defined $_repack) {
 		$_repack = 1000 if ($_repack <= 0);
 		$_repack_nr = $_repack;
-		$_repack_flags ||= '';
+		$_repack_flags ||= '-d';
 	}
 }
 
@@ -2352,7 +2375,7 @@ sub libsvn_get_file {
 	close $ho or croak $?;
 	$hash =~ /^$sha1$/o or die "not a sha1: $hash\n";
 	print $gui $mode,' ',$hash,"\t",$p,"\0" or croak $!;
-	close $fd or croak $!;
+	close $fd or croak $?;
 }
 
 sub libsvn_log_entry {
@@ -2381,7 +2404,7 @@ sub process_rm {
 		while (<$ls>) {
 			print $gui '0 ',0 x 40,"\t",$_ or croak $!;
 		}
-		close $ls or croak $!;
+		close $ls or croak $?;
 	} else {
 		print $gui '0 ',0 x 40,"\t",$f,"\0" or croak $!;
 	}
@@ -2411,7 +2434,7 @@ sub libsvn_fetch {
 		$pool->clear;
 	}
 	libsvn_get_file($gui, $_, $rev) foreach (@amr);
-	close $gui or croak $!;
+	close $gui or croak $?;
 	return libsvn_log_entry($rev, $author, $date, $msg, [$last_commit]);
 }
 
@@ -2514,36 +2537,30 @@ sub revisions_eq {
 }
 
 sub libsvn_find_parent_branch {
-	return undef; # XXX this function is disabled atm (not tested enough)
 	my ($paths, $rev, $author, $date, $msg) = @_;
 	my $svn_path = '/'.$SVN_PATH;
 
 	# look for a parent from another branch:
-	foreach (keys %$paths) {
-		next if ($_ ne $svn_path);
-		my $i = $paths->{$_};
-		my $branch_from = $i->copyfrom_path or next;
-		my $r = $i->copyfrom_rev;
-		print STDERR  "Found possible branch point: ",
-					"$branch_from => $svn_path, $r\n";
-		$branch_from =~ s#^/##;
-		my $l_map = read_url_paths();
-		my $url = $SVN->{url};
-		defined $l_map->{$url} or next;
-		my $id  = $l_map->{$url}->{$branch_from} or next;
-		my ($r0, $parent) = find_rev_before($r,$id,1);
-		if (defined $r0 && defined $parent &&
-					revisions_eq($branch_from, $r0, $r)) {
-			unlink $GIT_SVN_INDEX;
-			print STDERR "Found branch parent: $parent\n";
-			sys(qw/git-read-tree/, $parent);
-			return libsvn_fetch($parent, $paths, $rev,
-						$author, $date, $msg);
-		} else {
-			print STDERR
-				"Nope, branch point not imported or unknown\n";
-		}
-	}
+	my $i = $paths->{$svn_path} or return;
+	my $branch_from = $i->copyfrom_path or return;
+	my $r = $i->copyfrom_rev;
+	print STDERR  "Found possible branch point: ",
+				"$branch_from => $svn_path, $r\n";
+	$branch_from =~ s#^/##;
+	my $l_map = read_url_paths();
+	my $url = $SVN->{url};
+	defined $l_map->{$url} or return;
+	my $id = $l_map->{$url}->{$branch_from} or return;
+	my ($r0, $parent) = find_rev_before($r,$id,1);
+	return unless (defined $r0 && defined $parent);
+	if (revisions_eq($branch_from, $r0, $r)) {
+		unlink $GIT_SVN_INDEX;
+		print STDERR "Found branch parent: $parent\n";
+		sys(qw/git-read-tree/, $parent);
+		return libsvn_fetch($parent, $paths, $rev,
+					$author, $date, $msg);
+	}
+	print STDERR "Nope, branch point not imported or unknown\n";
 	return undef;
 }
 
@@ -2556,7 +2573,7 @@ sub libsvn_new_tree {
 	my $pool = SVN::Pool->new;
 	libsvn_traverse($gui, '', $SVN_PATH, $rev, $pool);
 	$pool->clear;
-	close $gui or croak $!;
+	close $gui or croak $?;
 	return libsvn_log_entry($rev, $author, $date, $msg);
 }
 
@@ -2630,7 +2647,7 @@ sub libsvn_commit_cb {
 			exit 1;
 		}
 	} else {
-		fetch_lib("$rev=$c");
+		fetch("$rev=$c");
 	}
 }
 
@@ -2664,7 +2681,6 @@ sub libsvn_skip_unknown_revs {
 	# 175002 - http(s)://
 	#   More codes may be discovered later...
 	if ($errno == 175002 || $errno == 160013) {
-		print STDERR "directory non-existent\n";
 		return;
 	}
 	croak "Error from SVN, ($errno): ", $err->expanded_message,"\n";
-- 
1.4.0

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

* [PATCH 3/3] git-svn: Eliminate temp file usage in libsvn_get_file()
  2006-06-15 20:55 ` [PATCH 2/3] git-svn: fix several small bugs, enable branch optimization Eric Wong
@ 2006-06-15 20:55   ` Eric Wong
  2006-06-16 17:57     ` [PATCH 0/4] git-svn: more improvements Eric Wong
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Wong @ 2006-06-15 20:55 UTC (permalink / raw)
  To: Junio C Hamano, git; +Cc: Eric Wong

This means we'll have a loose object when we encounter a symlink
but that's not the common case.

We also don't have to worry about svn:eol-style when using the
SVN libraries, either.  So remove the code to deal with that.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 contrib/git-svn/git-svn.perl |   56 +++++++++++++++++-------------------------
 1 files changed, 23 insertions(+), 33 deletions(-)

diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 27f1d68..149149f 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -31,6 +31,7 @@ use File::Path qw/mkpath/;
 use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev pass_through/;
 use File::Spec qw//;
 use POSIX qw/strftime/;
+use IPC::Open3;
 use Memoize;
 memoize('revisions_eq');
 
@@ -2335,47 +2336,36 @@ sub libsvn_get_file {
 	my $p = $f;
 	return unless ($p =~ s#^\Q$SVN_PATH\E/?##);
 
-	my $fd = IO::File->new_tmpfile or croak $!;
+	my ($hash, $pid, $in, $out);
 	my $pool = SVN::Pool->new;
-	my ($r, $props) = $SVN->get_file($f, $rev, $fd, $pool);
+	defined($pid = open3($in, $out, '>&STDERR',
+				qw/git-hash-object -w --stdin/)) or croak $!;
+	my ($r, $props) = $SVN->get_file($f, $rev, $in, $pool);
+	$in->flush == 0 or croak $!;
+	close $in or croak $!;
 	$pool->clear;
-	$fd->flush == 0 or croak $!;
-	seek $fd, 0, 0 or croak $!;
-	if (my $es = $props->{'svn:eol-style'}) {
-		my $new_fd = IO::File->new_tmpfile or croak $!;
-		eol_cp_fd($fd, $new_fd, $es);
-		close $fd or croak $!;
-		$fd = $new_fd;
-		seek $fd, 0, 0 or croak $!;
-		$fd->flush == 0 or croak $!;
-	}
-	my $mode = '100644';
-	if (exists $props->{'svn:executable'}) {
-		$mode = '100755';
-	}
+	chomp($hash = do { local $/; <$out> });
+	close $out or croak $!;
+	waitpid $pid, 0;
+	$hash =~ /^$sha1$/o or die "not a sha1: $hash\n";
+
+	my $mode = exists $props->{'svn:executable'} ? '100755' : '100644';
 	if (exists $props->{'svn:special'}) {
 		$mode = '120000';
-		local $/;
-		my $link = <$fd>;
+		my $link = `git-cat-file blob $hash`;
 		$link =~ s/^link // or die "svn:special file with contents: <",
 						$link, "> is not understood\n";
-		seek $fd, 0, 0 or croak $!;
-		truncate $fd, 0 or croak $!;
-		print $fd $link or croak $!;
-		seek $fd, 0, 0 or croak $!;
-		$fd->flush == 0 or croak $!;
-	}
-	my $pid = open my $ho, '-|';
-	defined $pid or croak $!;
-	if (!$pid) {
-		open STDIN, '<&', $fd or croak $!;
-		exec qw/git-hash-object -w --stdin/ or croak $!;
+		defined($pid = open3($in, $out, '>&STDERR',
+				qw/git-hash-object -w --stdin/)) or croak $!;
+		print $in $link;
+		$in->flush == 0 or croak $!;
+		close $in or croak $!;
+		chomp($hash = do { local $/; <$out> });
+		close $out or croak $!;
+		waitpid $pid, 0;
+		$hash =~ /^$sha1$/o or die "not a sha1: $hash\n";
 	}
-	chomp(my $hash = do { local $/; <$ho> });
-	close $ho or croak $?;
-	$hash =~ /^$sha1$/o or die "not a sha1: $hash\n";
 	print $gui $mode,' ',$hash,"\t",$p,"\0" or croak $!;
-	close $fd or croak $?;
 }
 
 sub libsvn_log_entry {
-- 
1.4.0

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

* [PATCH 0/4] git-svn: more improvements
  2006-06-15 20:55   ` [PATCH 3/3] git-svn: Eliminate temp file usage in libsvn_get_file() Eric Wong
@ 2006-06-16 17:57     ` Eric Wong
  2006-06-16 17:57       ` [PATCH 1/4] git-svn: bugfix and optimize the 'log' command Eric Wong
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Wong @ 2006-06-16 17:57 UTC (permalink / raw)
  To: Junio C Hamano, git

Another round of patches to git-svn, all depending on previous patches.

I've also setup a pullable repo here for all my latest git-svn stuff:
	git://git.bogomips.org/git-svn.git
	(http:// also works)

-- 
Eric Wong

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

* [PATCH 1/4] git-svn: bugfix and optimize the 'log' command
  2006-06-16 17:57     ` [PATCH 0/4] git-svn: more improvements Eric Wong
@ 2006-06-16 17:57       ` Eric Wong
  2006-06-16 17:57         ` [PATCH 2/4] git-svn: tests no longer fail if LC_ALL is not a UTF-8 locale Eric Wong
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Wong @ 2006-06-16 17:57 UTC (permalink / raw)
  To: Junio C Hamano, git; +Cc: Eric Wong

Revisions with long commit messages were being skipped, since
the 'git-svn-id' metadata line was at the end and git-log uses a
32k buffer to print the commits.

Also the last 'git-svn-id' metadata line in a commit is always
the valid one, so make sure we use that, as well.

Made the verbose flag work by passing the correct option switch
('--summary') to git-log.

Finally, optimize -r/--revision argument handling by passing
the appropriate limits to revision

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 contrib/git-svn/git-svn.perl |   60 ++++++++++++++++++++++++++++++++++++------
 1 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 149149f..417fcf1 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -663,17 +663,15 @@ sub show_log {
 	my $pid = open(my $log,'-|');
 	defined $pid or croak $!;
 	if (!$pid) {
-		my @rl = (qw/git-log --abbrev-commit --pretty=raw
-				--default/, "remotes/$GIT_SVN");
-		push @rl, '--raw' if $_verbose;
-		exec(@rl, @args) or croak $!;
+		exec(git_svn_log_cmd($r_min,$r_max), @args) or croak $!;
 	}
 	setup_pager();
 	my (@k, $c, $d);
+
 	while (<$log>) {
 		if (/^commit ($sha1_short)/o) {
 			my $cmt = $1;
-			if ($c && defined $c->{r} && $c->{r} != $r_last) {
+			if ($c && cmt_showable($c) && $c->{r} != $r_last) {
 				$r_last = $c->{r};
 				process_commit($c, $r_min, $r_max, \@k) or
 								goto out;
@@ -692,8 +690,7 @@ sub show_log {
 		} elsif ($d) {
 			push @{$c->{diff}}, $_;
 		} elsif (/^    (git-svn-id:.+)$/) {
-			my ($url, $rev, $uuid) = extract_metadata($1);
-			$c->{r} = $rev;
+			(undef, $c->{r}, undef) = extract_metadata($1);
 		} elsif (s/^    //) {
 			push @{$c->{l}}, $_;
 		}
@@ -715,6 +712,52 @@ out:
 
 ########################### utility functions #########################
 
+sub cmt_showable {
+	my ($c) = @_;
+	return 1 if defined $c->{r};
+	if ($c->{l} && $c->{l}->[-1] eq "...\n" &&
+				$c->{a_raw} =~ /\@([a-f\d\-]+)>$/) {
+		my @msg = safe_qx(qw/git-cat-file commit/, $c->{c});
+		shift @msg while ($msg[0] ne "\n");
+		shift @msg;
+		@{$c->{l}} = grep !/^git-svn-id: /, @msg;
+
+		(undef, $c->{r}, undef) = extract_metadata(
+				(grep(/^git-svn-id: /, @msg))[-1]);
+	}
+	return defined $c->{r};
+}
+
+sub git_svn_log_cmd {
+	my ($r_min, $r_max) = @_;
+	my @cmd = (qw/git-log --abbrev-commit --pretty=raw
+			--default/, "refs/remotes/$GIT_SVN");
+	push @cmd, '--summary' if $_verbose;
+	return @cmd unless defined $r_max;
+	if ($r_max == $r_min) {
+		push @cmd, '--max-count=1';
+		if (my $c = revdb_get($REVDB, $r_max)) {
+			push @cmd, $c;
+		}
+	} else {
+		my ($c_min, $c_max);
+		$c_max = revdb_get($REVDB, $r_max);
+		$c_min = revdb_get($REVDB, $r_min);
+		if ($c_min && $c_max) {
+			if ($r_max > $r_max) {
+				push @cmd, "$c_min..$c_max";
+			} else {
+				push @cmd, "$c_max..$c_min";
+			}
+		} elsif ($r_max > $r_min) {
+			push @cmd, $c_max;
+		} else {
+			push @cmd, $c_min;
+		}
+	}
+	return @cmd;
+}
+
 sub fetch_child_id {
 	my $id = shift;
 	print "Fetching $id\n";
@@ -2206,6 +2249,7 @@ sub setup_pager { # translated to Perl f
 sub get_author_info {
 	my ($dest, $author, $t, $tz) = @_;
 	$author =~ s/(?:^\s*|\s*$)//g;
+	$dest->{a_raw} = $author;
 	my $_a;
 	if ($_authors) {
 		$_a = $rusers{$author} || undef;
@@ -2440,7 +2484,7 @@ sub svn_grab_base_rev {
 	close $fh;
 	if (defined $c && length $c) {
 		my ($url, $rev, $uuid) = extract_metadata((grep(/^git-svn-id: /,
-			safe_qx(qw/git-cat-file commit/, $c)))[0]);
+			safe_qx(qw/git-cat-file commit/, $c)))[-1]);
 		return ($rev, $c);
 	}
 	return (undef, undef);
-- 
1.4.0

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

* [PATCH 2/4] git-svn: tests no longer fail if LC_ALL is not a UTF-8 locale
  2006-06-16 17:57       ` [PATCH 1/4] git-svn: bugfix and optimize the 'log' command Eric Wong
@ 2006-06-16 17:57         ` Eric Wong
  2006-06-16 17:57           ` [PATCH 3/4] git-svn: svn (command-line) 1.0.x compatibility Eric Wong
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Wong @ 2006-06-16 17:57 UTC (permalink / raw)
  To: Junio C Hamano, git; +Cc: Eric Wong

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 contrib/git-svn/Makefile                   |    5 +++--
 contrib/git-svn/t/t0000-contrib-git-svn.sh |    8 ++++++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/contrib/git-svn/Makefile b/contrib/git-svn/Makefile
index d73aa56..6aedb10 100644
--- a/contrib/git-svn/Makefile
+++ b/contrib/git-svn/Makefile
@@ -32,9 +32,10 @@ test: git-svn
 	cd t && $(SHELL) ./t0000-contrib-git-svn.sh $(TEST_FLAGS)
 	cd t && $(SHELL) ./t0001-contrib-git-svn-props.sh $(TEST_FLAGS)
 
+# we can test NO_OPTIMIZE_COMMITS independently of LC_ALL
 full-test:
-	$(MAKE) test GIT_SVN_NO_LIB=1 GIT_SVN_NO_OPTIMIZE_COMMITS=1
-	$(MAKE) test GIT_SVN_NO_LIB=0 GIT_SVN_NO_OPTIMIZE_COMMITS=1
+	$(MAKE) test GIT_SVN_NO_LIB=1 GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
+	$(MAKE) test GIT_SVN_NO_LIB=0 GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
 	$(MAKE) test GIT_SVN_NO_LIB=1 GIT_SVN_NO_OPTIMIZE_COMMITS=0 \
 							LC_ALL=en_US.UTF-8
 	$(MAKE) test GIT_SVN_NO_LIB=0 GIT_SVN_NO_OPTIMIZE_COMMITS=0 \
diff --git a/contrib/git-svn/t/t0000-contrib-git-svn.sh b/contrib/git-svn/t/t0000-contrib-git-svn.sh
index f896e2c..0f52746 100644
--- a/contrib/git-svn/t/t0000-contrib-git-svn.sh
+++ b/contrib/git-svn/t/t0000-contrib-git-svn.sh
@@ -194,8 +194,12 @@ test_expect_success "$name" \
      diff -u a b"
 
 name='check imported tree checksums expected tree checksums'
-cat > expected <<\EOF
-tree f735671b89a7eb30cab1d8597de35bd4271ab813
+rm -f expected
+if test -n "$GIT_SVN_LC_ALL" && echo $GIT_SVN_LC_ALL | grep -q '\.UTF-8$'
+then
+	echo tree f735671b89a7eb30cab1d8597de35bd4271ab813 > expected
+fi
+cat >> expected <<\EOF
 tree 4b9af72bb861eaed053854ec502cf7df72618f0f
 tree 031b8d557afc6fea52894eaebb45bec52f1ba6d1
 tree 0b094cbff17168f24c302e297f55bfac65eb8bd3
-- 
1.4.0

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

* [PATCH 3/4] git-svn: svn (command-line) 1.0.x compatibility
  2006-06-16 17:57         ` [PATCH 2/4] git-svn: tests no longer fail if LC_ALL is not a UTF-8 locale Eric Wong
@ 2006-06-16 17:57           ` Eric Wong
  2006-06-16 17:57             ` [PATCH 4/4] git-svn: rebuild convenience and bugfixes Eric Wong
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Wong @ 2006-06-16 17:57 UTC (permalink / raw)
  To: Junio C Hamano, git; +Cc: Eric Wong

Tested on a plain Ubuntu Warty installation
using subversion 1.0.6-1.2ubuntu3

svn add --force was never needed, as it only affected
directories, which git (thankfully) doesn't track

The 1.0.x also didn't support symlinks(!), so allow NO_SYMLINK
to be defined for running tests

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 contrib/git-svn/git-svn.perl               |    4 +
 contrib/git-svn/t/t0000-contrib-git-svn.sh |   90 +++++++++++++++-------------
 2 files changed, 51 insertions(+), 43 deletions(-)

diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index 417fcf1..ab1d065 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -1306,12 +1306,12 @@ sub svn_checkout_tree {
 		} elsif ($m->{chg} eq 'T') {
 			sys(qw(svn rm --force),$m->{file_b});
 			apply_mod_line_blob($m);
-			sys(qw(svn add --force), $m->{file_b});
+			sys(qw(svn add), $m->{file_b});
 			svn_check_prop_executable($m);
 		} elsif ($m->{chg} eq 'A') {
 			svn_ensure_parent_path( $m->{file_b} );
 			apply_mod_line_blob($m);
-			sys(qw(svn add --force), $m->{file_b});
+			sys(qw(svn add), $m->{file_b});
 			svn_check_prop_executable($m);
 		} else {
 			croak "Invalid chg: $m->{chg}\n";
diff --git a/contrib/git-svn/t/t0000-contrib-git-svn.sh b/contrib/git-svn/t/t0000-contrib-git-svn.sh
index 0f52746..443d518 100644
--- a/contrib/git-svn/t/t0000-contrib-git-svn.sh
+++ b/contrib/git-svn/t/t0000-contrib-git-svn.sh
@@ -11,7 +11,10 @@ mkdir import
 cd import
 
 echo foo > foo
-ln -s foo foo.link
+if test -z "$NO_SYMLINK"
+then
+	ln -s foo foo.link
+fi
 mkdir -p dir/a/b/c/d/e
 echo 'deep dir' > dir/a/b/c/d/e/file
 mkdir -p bar
@@ -129,46 +132,45 @@ test_expect_success "$name" \
 
 
 
-name='executable file becomes a symlink to bar/zzz (file)'
-rm exec.sh
-ln -s bar/zzz exec.sh
-git update-index exec.sh
-git commit -m "$name"
-
-test_expect_success "$name" \
-    "git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&
-     svn up $SVN_TREE &&
-     test -L $SVN_TREE/exec.sh"
-
-
-
-name='new symlink is added to a file that was also just made executable'
-chmod +x bar/zzz
-ln -s bar/zzz exec-2.sh
-git update-index --add bar/zzz exec-2.sh
-git commit -m "$name"
-
-test_expect_success "$name" \
-    "git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&
-     svn up $SVN_TREE &&
-     test -x $SVN_TREE/bar/zzz &&
-     test -L $SVN_TREE/exec-2.sh"
-
-
-
-name='modify a symlink to become a file'
-git help > help || true
-rm exec-2.sh
-cp help exec-2.sh
-git update-index exec-2.sh
-git commit -m "$name"
-
-test_expect_success "$name" \
-    "git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&
-     svn up $SVN_TREE &&
-     test -f $SVN_TREE/exec-2.sh &&
-     test ! -L $SVN_TREE/exec-2.sh &&
-     diff -u help $SVN_TREE/exec-2.sh"
+if test -z "$NO_SYMLINK"
+then
+	name='executable file becomes a symlink to bar/zzz (file)'
+	rm exec.sh
+	ln -s bar/zzz exec.sh
+	git update-index exec.sh
+	git commit -m "$name"
+
+	test_expect_success "$name" \
+	    "git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&
+	     svn up $SVN_TREE &&
+	     test -L $SVN_TREE/exec.sh"
+
+	name='new symlink is added to a file that was also just made executable'
+	chmod +x bar/zzz
+	ln -s bar/zzz exec-2.sh
+	git update-index --add bar/zzz exec-2.sh
+	git commit -m "$name"
+
+	test_expect_success "$name" \
+	    "git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&
+	     svn up $SVN_TREE &&
+	     test -x $SVN_TREE/bar/zzz &&
+	     test -L $SVN_TREE/exec-2.sh"
+
+	name='modify a symlink to become a file'
+	git help > help || true
+	rm exec-2.sh
+	cp help exec-2.sh
+	git update-index exec-2.sh
+	git commit -m "$name"
+
+	test_expect_success "$name" \
+	    "git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&
+	     svn up $SVN_TREE &&
+	     test -f $SVN_TREE/exec-2.sh &&
+	     test ! -L $SVN_TREE/exec-2.sh &&
+	     diff -u help $SVN_TREE/exec-2.sh"
+fi
 
 
 if test -n "$GIT_SVN_LC_ALL" && echo $GIT_SVN_LC_ALL | grep -q '\.UTF-8$'
@@ -193,6 +195,12 @@ test_expect_success "$name" \
      git-rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&
      diff -u a b"
 
+if test -n "$NO_SYMLINK"
+then
+	test_done
+	exit 0
+fi
+
 name='check imported tree checksums expected tree checksums'
 rm -f expected
 if test -n "$GIT_SVN_LC_ALL" && echo $GIT_SVN_LC_ALL | grep -q '\.UTF-8$'
-- 
1.4.0

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

* [PATCH 4/4] git-svn: rebuild convenience and bugfixes
  2006-06-16 17:57           ` [PATCH 3/4] git-svn: svn (command-line) 1.0.x compatibility Eric Wong
@ 2006-06-16 17:57             ` Eric Wong
  0 siblings, 0 replies; 8+ messages in thread
From: Eric Wong @ 2006-06-16 17:57 UTC (permalink / raw)
  To: Junio C Hamano, git; +Cc: Eric Wong

We will now automatically fetch the refs/remotes/git-svn ref
from origin and store a Pull: line for it.

--remote=<origin> may be passed if your remote is named something
other than 'origin'

Also, remember to make GIT_SVN_DIR whenever we need to create
.rev_db

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 contrib/git-svn/git-svn.perl |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index ab1d065..da0ff9a 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -42,7 +42,7 @@ my $_optimize_commits = 1 unless $ENV{GI
 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, $_cp_similarity,
+	$_find_copies_harder, $_l, $_cp_similarity, $_cp_remote,
 	$_repack, $_repack_nr, $_repack_flags,
 	$_template, $_shared, $_no_default_regex, $_no_graft_copy,
 	$_limit, $_verbose, $_incremental, $_oneline, $_l_fmt, $_show_commit,
@@ -86,6 +86,7 @@ my %cmd = (
 			{ 'revision|r=i' => \$_revision } ],
 	rebuild => [ \&rebuild, "Rebuild git-svn metadata (after git clone)",
 			{ 'no-ignore-externals' => \$_no_ignore_ext,
+			  'copy-remote|remote=s' => \$_cp_remote,
 			  'upgrade' => \$_upgrade } ],
 	'graft-branches' => [ \&graft_branches,
 			'Detect merges/branches from already imported history',
@@ -134,7 +135,7 @@ init_vars();
 load_authors() if $_authors;
 load_all_refs() if $_branch_all_refs;
 svn_compat_check();
-migration_check() unless $cmd =~ /^(?:init|multi-init)$/;
+migration_check() unless $cmd =~ /^(?:init|rebuild|multi-init)$/;
 $cmd{$cmd}->[0]->(@ARGV);
 exit 0;
 
@@ -174,6 +175,9 @@ sub version {
 }
 
 sub rebuild {
+	if (quiet_run(qw/git-rev-parse --verify/,"refs/remotes/$GIT_SVN^0")) {
+		copy_remote_ref();
+	}
 	$SVN_URL = shift or undef;
 	my $newest_rev = 0;
 	if ($_upgrade) {
@@ -1940,6 +1944,7 @@ sub svn_cmd_checkout {
 
 sub check_upgrade_needed {
 	if (!-r $REVDB) {
+		-d $GIT_SVN_DIR or mkpath([$GIT_SVN_DIR]);
 		open my $fh, '>>',$REVDB or croak $!;
 		close $fh;
 	}
@@ -2052,6 +2057,7 @@ sub migrate_revdb {
 			init_vars();
 			exit 0 if -r $REVDB;
 			print "Upgrading svn => git mapping...\n";
+			-d $GIT_SVN_DIR or mkpath([$GIT_SVN_DIR]);
 			open my $fh, '>>',$REVDB or croak $!;
 			close $fh;
 			rebuild();
@@ -2763,6 +2769,17 @@ sub revdb_get {
 	return $ret;
 }
 
+sub copy_remote_ref {
+	my $origin = $_cp_remote ? $_cp_remote : 'origin';
+	my $ref = "refs/remotes/$GIT_SVN";
+	if (safe_qx('git-ls-remote', $origin, $ref)) {
+		sys(qw/git fetch/, $origin, "$ref:$ref");
+	} else {
+		die "Unable to find remote reference: ",
+				"refs/remotes/$GIT_SVN on $origin\n";
+	}
+}
+
 package SVN::Git::Editor;
 use vars qw/@ISA/;
 use strict;
-- 
1.4.0

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

end of thread, other threads:[~2006-06-16 17:57 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-15 20:55 [PATCH 1/3] git-svn: avoid creating some small files Eric Wong
2006-06-15 20:55 ` [PATCH 2/3] git-svn: fix several small bugs, enable branch optimization Eric Wong
2006-06-15 20:55   ` [PATCH 3/3] git-svn: Eliminate temp file usage in libsvn_get_file() Eric Wong
2006-06-16 17:57     ` [PATCH 0/4] git-svn: more improvements Eric Wong
2006-06-16 17:57       ` [PATCH 1/4] git-svn: bugfix and optimize the 'log' command Eric Wong
2006-06-16 17:57         ` [PATCH 2/4] git-svn: tests no longer fail if LC_ALL is not a UTF-8 locale Eric Wong
2006-06-16 17:57           ` [PATCH 3/4] git-svn: svn (command-line) 1.0.x compatibility Eric Wong
2006-06-16 17:57             ` [PATCH 4/4] git-svn: rebuild convenience and bugfixes 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).