git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/3] git-svn: Eliminate temp file usage in libsvn_get_file()

From
EWEric Wong <normalperson@yhbt.net>
Date
Jun 15, 2006, 20:55 UTC
Message-ID
<11504049343825-git-send-email-normalperson@yhbt.net>
In-Reply-To
<11504049322660-git-send-email-normalperson@yhbt.net>

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
Previous: Eric WongNext: Eric Wong
Message 3 of 8 in “git-svn: avoid creating some small files”
  1. 1/3 git-svn: avoid creating some small filesEric Wong, Jun 15, 2006
  2. 2/3 git-svn: fix several small bugs, enable branch optimizationEric Wong, Jun 15, 2006
  3. 3/3 git-svn: Eliminate temp file usage in libsvn_get_file()Eric Wong, Jun 15, 2006
  4. 0/4 git-svn: more improvementsEric Wong, Jun 16, 2006
  5. 1/4 git-svn: bugfix and optimize the 'log' commandEric Wong, Jun 16, 2006
  6. 2/4 git-svn: tests no longer fail if LC_ALL is not a UTF-8 localeEric Wong, Jun 16, 2006
  7. 3/4 git-svn: svn (command-line) 1.0.x compatibilityEric Wong, Jun 16, 2006
  8. 4/4 git-svn: rebuild convenience and bugfixesEric Wong, Jun 16, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.