Git development
 help / color / mirror / Atom feed
* [PATCH 5/9] git-cat-file: Add --separator option
From: Adam Roben @ 2007-10-23  5:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Adam Roben
In-Reply-To: <1193118397-4696-5-git-send-email-aroben@apple.com>

This lets the user specify a string to be printed in between the output from
each object passed on stdin.

Signed-off-by: Adam Roben <aroben@apple.com>
---
 Documentation/git-cat-file.txt |    7 ++++++-
 builtin-cat-file.c             |   28 +++++++++++++++++++++++++---
 t/t1005-cat-file.sh            |   36 +++++++++++++++++++++++++++++++++++-
 3 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt
index 588d71a..7a59a5e 100644
--- a/Documentation/git-cat-file.txt
+++ b/Documentation/git-cat-file.txt
@@ -8,7 +8,7 @@ git-cat-file - Provide content or type/size information for repository objects
 
 SYNOPSIS
 --------
-'git-cat-file' [-t | -s | -e | -p | <type>] [--stdin | <object>]
+'git-cat-file' [-t | -s | -e | -p | <type>] [--stdin [--separator <string>] | <object>]
 
 DESCRIPTION
 -----------
@@ -27,6 +27,11 @@ OPTIONS
 	Read object names from stdin instead of specifying one on the
 	command line.
 
+--separator::
+	A string to print in between the output for each object passed on
+	stdin. A newline will be appended to the separator each time it is
+	printed.
+
 -t::
 	Instead of the content, show the object type identified by
 	<object>.
diff --git a/builtin-cat-file.c b/builtin-cat-file.c
index 0f1ffe5..9ae3184 100644
--- a/builtin-cat-file.c
+++ b/builtin-cat-file.c
@@ -92,6 +92,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
 		type = sha1_object_info(sha1, NULL);
 		if (type > 0) {
 			printf("%s\n", typename(type));
+			fflush(stdout);
 			return 0;
 		}
 		break;
@@ -100,6 +101,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
 		type = sha1_object_info(sha1, &size);
 		if (type > 0) {
 			printf("%lu\n", size);
+			fflush(stdout);
 			return 0;
 		}
 		break;
@@ -143,14 +145,16 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
 	return 0;
 }
 
-static const char cat_file_usage[] = "git-cat-file [-t|-s|-e|-p|<type>] [--stdin | <sha1>]";
+static const char cat_file_usage[] = "git-cat-file [-t|-s|-e|-p|<type>] [--stdin [--separator <string>] | <sha1>]";
+
+static const char *separator;
 
 int cmd_cat_file(int argc, const char **argv, const char *prefix)
 {
 	int i, opt = 0;
 	int read_stdin = 0;
 	const char *exp_type = 0, *obj_name = 0;
-	struct strbuf buf;
+	struct strbuf buf, sbuf;
 
 	git_config(git_default_config);
 
@@ -168,6 +172,13 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
 		    continue;
 		}
 
+		if (!strcmp(arg, "--separator")) {
+			if (++i == argc)
+				usage(cat_file_usage);
+			separator = argv[i];
+			continue;
+		}
+
 		if (arg[0] == '-')
 			usage(cat_file_usage);
 
@@ -184,18 +195,29 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
 	}
 
 	if (!read_stdin) {
-	    if (!exp_type || !obj_name)
+	    if (!exp_type || !obj_name || separator)
 		usage(cat_file_usage);
 	    return cat_one_file(opt, exp_type, obj_name);
 	}
 
+	if (separator) {
+		strbuf_init(&sbuf, 0);
+		strbuf_addstr(&sbuf, separator);
+		strbuf_addch(&sbuf, '\n');
+	}
+
 	strbuf_init(&buf, 0);
 	while (strbuf_getline(&buf, stdin, '\n') != EOF) {
 		int error = cat_one_file(opt, exp_type, buf.buf);
 		if (error)
 			return error;
+		if (separator)
+			write_or_die(1, sbuf.buf, sbuf.len);
 	}
 	strbuf_release(&buf);
 
+	if (separator)
+		strbuf_release(&sbuf);
+
 	return 0;
 }
diff --git a/t/t1005-cat-file.sh b/t/t1005-cat-file.sh
index 49eb89d..52a3efd 100755
--- a/t/t1005-cat-file.sh
+++ b/t/t1005-cat-file.sh
@@ -99,7 +99,41 @@ $commit_size
 $tag_size"
 
 test_expect_success \
-    "Pass object hashes on stdin" \
+    "Print sizes for object hashes on stdin" \
     "test \"$sizes\" = \"$(echo "$sha1s" | git cat-file -s --stdin)\""
 
+separator="TESTSEPARATOR"
+
+separated_sizes="$hello_size
+$separator
+$tree_size
+$separator
+$commit_size
+$separator
+$tag_size
+$separator"
+
+test_expect_success \
+    "Print sizes for object hashes on stdin with --separator" \
+    "test \"$separated_sizes\" = \"$(echo "$sha1s" | git cat-file -s --stdin --separator $separator)\""
+
+sha1s="$hello_sha1
+$hello_sha1"
+
+contents="$hello_content
+$hello_content"
+
+separated_contents="$hello_content
+$separator
+$hello_content
+$separator"
+
+test_expect_success \
+    "Print objects for object hashes on stdin" \
+    "test \"$contents\" = \"$(echo "$sha1s" | git cat-file blob --stdin)\""
+
+test_expect_success \
+    "Print objects for object hashes on stdin with --separator" \
+    "test \"$separated_contents\" = \"$(echo "$sha1s" | git cat-file blob --stdin --separator $separator)\""
+
 test_done
-- 
1.5.3.4.1333.ga2f32

^ permalink raw reply related

* [PATCH 6/9] Add tests for git hash-object
From: Adam Roben @ 2007-10-23  5:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Adam Roben
In-Reply-To: <1193118397-4696-6-git-send-email-aroben@apple.com>


Signed-off-by: Adam Roben <aroben@apple.com>
---
 t/t1006-hash-object.sh |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)
 create mode 100755 t/t1006-hash-object.sh

diff --git a/t/t1006-hash-object.sh b/t/t1006-hash-object.sh
new file mode 100755
index 0000000..77b8eca
--- /dev/null
+++ b/t/t1006-hash-object.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+test_description='git hash-object'
+
+. ./test-lib.sh
+
+hello_content="Hello World"
+hello_sha1=557db03de997c86a4a028e1ebd3a1ceb225be238
+echo "$hello_content" > hello
+
+test_expect_success \
+    'hash a file' \
+    "test $hello_sha1 = $(git hash-object hello)"
+
+test_expect_success \
+    'hash from stdin' \
+    "test $hello_sha1 = $(echo "$hello_content" | git hash-object --stdin)"
+
+test_expect_success \
+    'hash a file and write to database' \
+    "test $hello_sha1 = $(git hash-object -w hello)"
+
+test_expect_success \
+    'hash from stdin and write to database' \
+    "test $hello_sha1 = $(echo "$hello_content" | git hash-object -w --stdin)"
+
+test_done
-- 
1.5.3.4.1333.ga2f32

^ permalink raw reply related

* [PATCH 7/9] git-hash-object: Add --stdin-paths option
From: Adam Roben @ 2007-10-23  5:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Adam Roben
In-Reply-To: <1193118397-4696-7-git-send-email-aroben@apple.com>

This allows multiple paths to be specified on stdin.

Signed-off-by: Adam Roben <aroben@apple.com>
---
 Documentation/git-hash-object.txt |    5 ++++-
 hash-object.c                     |   29 ++++++++++++++++++++++++++++-
 t/t1006-hash-object.sh            |   22 ++++++++++++++++++++++
 3 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt
index 616f196..50fc401 100644
--- a/Documentation/git-hash-object.txt
+++ b/Documentation/git-hash-object.txt
@@ -8,7 +8,7 @@ git-hash-object - Compute object ID and optionally creates a blob from a file
 
 SYNOPSIS
 --------
-'git-hash-object' [-t <type>] [-w] [--stdin] [--] <file>...
+'git-hash-object' [-t <type>] [-w] [--stdin | --stdin-paths] [--] <file>...
 
 DESCRIPTION
 -----------
@@ -32,6 +32,9 @@ OPTIONS
 --stdin::
 	Read the object from standard input instead of from a file.
 
+--stdin-paths::
+	Read file names from stdin instead of from the command-line.
+
 Author
 ------
 Written by Junio C Hamano <junkio@cox.net>
diff --git a/hash-object.c b/hash-object.c
index 18f5017..fd96d50 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -20,6 +20,7 @@ static void hash_object(const char *path, enum object_type type, int write_objec
 		    ? "Unable to add %s to database"
 		    : "Unable to hash %s", path);
 	printf("%s\n", sha1_to_hex(sha1));
+	maybe_flush_or_die(stdout, "hash to stdout");
 }
 
 static void hash_stdin(const char *type, int write_object)
@@ -31,7 +32,7 @@ static void hash_stdin(const char *type, int write_object)
 }
 
 static const char hash_object_usage[] =
-"git-hash-object [-t <type>] [-w] [--stdin] <file>...";
+"git-hash-object [-t <type>] [-w] [--stdin | --stdin-paths] <file>...";
 
 int main(int argc, char **argv)
 {
@@ -41,6 +42,7 @@ int main(int argc, char **argv)
 	const char *prefix = NULL;
 	int prefix_length = -1;
 	int no_more_flags = 0;
+	int found_stdin_flag = 0;
 
 	for (i = 1 ; i < argc; i++) {
 		if (!no_more_flags && argv[i][0] == '-') {
@@ -62,7 +64,32 @@ int main(int argc, char **argv)
 			}
 			else if (!strcmp(argv[i], "--help"))
 				usage(hash_object_usage);
+			else if (!strcmp(argv[i], "--stdin-paths")) {
+				struct strbuf buf, nbuf;
+
+				if (found_stdin_flag)
+					die("Can't use both --stdin and --stdin-paths");
+				found_stdin_flag = 1;
+
+				strbuf_init(&buf, 0);
+				strbuf_init(&nbuf, 0);
+				while (strbuf_getline(&buf, stdin, '\n') != EOF) {
+					if (buf.buf[0] == '"') {
+						strbuf_reset(&nbuf);
+						if (unquote_c_style(&nbuf, buf.buf, NULL))
+							die("line is badly quoted");
+						strbuf_swap(&buf, &nbuf);
+					}
+					hash_object(buf.buf, type_from_string(type), write_object);
+				}
+				strbuf_release(&buf);
+				strbuf_release(&nbuf);
+			}
 			else if (!strcmp(argv[i], "--stdin")) {
+				if (found_stdin_flag)
+					die("Can't use both --stdin and --stdin-paths");
+				found_stdin_flag = 1;
+
 				hash_stdin(type, write_object);
 			}
 			else
diff --git a/t/t1006-hash-object.sh b/t/t1006-hash-object.sh
index 77b8eca..e6da1c1 100755
--- a/t/t1006-hash-object.sh
+++ b/t/t1006-hash-object.sh
@@ -24,4 +24,26 @@ test_expect_success \
     'hash from stdin and write to database' \
     "test $hello_sha1 = $(echo "$hello_content" | git hash-object -w --stdin)"
 
+example_content="Silly example"
+example_sha1=f24c74a2e500f5ee1332c86b94199f52b1d1d962
+echo "$example_content" > example
+
+filenames="hello
+example"
+
+sha1s="$hello_sha1
+$example_sha1"
+
+test_expect_success \
+    'hash two files with names on stdin' \
+    "test \"$sha1s\" = \"$(echo "$filenames" | git hash-object --stdin-paths)\""
+
+test_expect_success \
+    'hash two files with names on stdin and write to database' \
+    "test \"$sha1s\" = \"$(echo "$filenames" | git hash-object --stdin-paths)\""
+
+test_expect_failure \
+    "Can't use --stdin and --stdin-paths together" \
+    "echo \"$filenames\" | git hash-object --stdin --stdin-paths"
+
 test_done
-- 
1.5.3.4.1333.ga2f32

^ permalink raw reply related

* [PATCH 9/9] git-svn: Make fetch ~1.7x faster
From: Adam Roben @ 2007-10-23  5:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Adam Roben, Eric Wong
In-Reply-To: <1193118397-4696-9-git-send-email-aroben@apple.com>

We were spending a lot of time forking/execing git-cat-file and
git-hash-object. We now use command_bidi_pipe to keep one instance of each
running and feed it input on stdin.

Signed-off-by: Adam Roben <aroben@apple.com>
---
 git-svn.perl |   94 ++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 72 insertions(+), 22 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index 22bb47b..8b72046 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -236,6 +236,8 @@ eval {
 };
 fatal $@ if $@;
 post_fetch_checkout();
+Git::Commands->close_cat_blob();
+Git::Commands->close_hash_object();
 exit 0;
 
 ####################### primary functions ######################
@@ -2683,14 +2685,8 @@ sub apply_textdelta {
 	my $base = IO::File->new_tmpfile;
 	$base->autoflush(1);
 	if ($fb->{blob}) {
-		defined (my $pid = fork) or croak $!;
-		if (!$pid) {
-			open STDOUT, '>&', $base or croak $!;
-			print STDOUT 'link ' if ($fb->{mode_a} == 120000);
-			exec qw/git-cat-file blob/, $fb->{blob} or croak $!;
-		}
-		waitpid $pid, 0;
-		croak $? if $?;
+		my $contents = Git::Commands->cat_blob($fb->{blob});
+		print $base $contents;
 
 		if (defined $exp) {
 			seek $base, 0, 0 or croak $!;
@@ -2729,13 +2725,7 @@ sub close_file {
 			$buf eq 'link ' or die "$path has mode 120000",
 			                       "but is not a link\n";
 		}
-		defined(my $pid = open my $out,'-|') or die "Can't fork: $!\n";
-		if (!$pid) {
-			open STDIN, '<&', $fh or croak $!;
-			exec qw/git-hash-object -w --stdin/ or croak $!;
-		}
-		chomp($hash = do { local $/; <$out> });
-		close $out or croak $!;
+		$hash = Git::Commands->hash_object($fh);
 		close $fh or croak $!;
 		$hash =~ /^[a-f\d]{40}$/ or die "not a sha1: $hash\n";
 		close $fb->{base} or croak $!;
@@ -3063,13 +3053,8 @@ sub chg_file {
 	} elsif ($m->{mode_a} =~ /^120/ && $m->{mode_b} !~ /^120/) {
 		$self->change_file_prop($fbat,'svn:special',undef);
 	}
-	defined(my $pid = fork) or croak $!;
-	if (!$pid) {
-		open STDOUT, '>&', $fh or croak $!;
-		exec qw/git-cat-file blob/, $m->{sha1_b} or croak $!;
-	}
-	waitpid $pid, 0;
-	croak $? if $?;
+	my $blob = Git::Commands->cat_blob($m->{sha1_b});
+	print $fh $blob;
 	$fh->flush == 0 or croak $!;
 	seek $fh, 0, 0 or croak $!;
 
@@ -4272,6 +4257,71 @@ sub full_path {
 	       $path . (length $self->{right} ? "/$self->{right}" : '');
 }
 
+package Git::Commands;
+use vars qw/$_cat_blob_pid $_cat_blob_in $_cat_blob_out $_cat_blob_ctx $_cat_blob_separator
+	    $_hash_object_pid $_hash_object_in $_hash_object_out $_hash_object_ctx/;
+use strict;
+use warnings;
+use File::Temp qw/tempfile/;
+use Git qw/command_bidi_pipe command_close_bidi_pipe/;
+
+sub _open_cat_blob_if_needed {
+	return if defined($_cat_blob_pid);
+	$_cat_blob_separator = "--------------GITCATFILESEPARATOR-----------";
+
+	($_cat_blob_pid, $_cat_blob_in, $_cat_blob_out, $_cat_blob_ctx) = command_bidi_pipe(qw(git-cat-file blob --stdin --separator), $_cat_blob_separator);
+}
+
+sub close_cat_blob {
+	return unless defined($_cat_blob_pid);
+
+	command_close_bidi_pipe($_cat_blob_pid, $_cat_blob_in, $_cat_blob_out, $_cat_blob_ctx);
+}
+
+sub cat_blob {
+	my (undef, $sha1) = @_;
+
+	_open_cat_blob_if_needed();
+	print $_cat_blob_out "$sha1\n";
+	my @file = ();
+	while (my $line = <$_cat_blob_in>) {
+		my $last = 0;
+		if ($line =~ s/\Q$_cat_blob_separator\E$//) {
+			chomp($line);
+			$last = 1;
+		}
+		push(@file, $line);
+		last if $last;
+	}
+	return join('', @file);
+}
+
+sub _open_hash_object_if_needed {
+	return if defined($_hash_object_pid);
+
+	($_hash_object_pid, $_hash_object_in, $_hash_object_out, $_hash_object_ctx) = command_bidi_pipe(qw(git-hash-object -w --stdin-paths));
+}
+
+sub close_hash_object {
+	return unless defined($_hash_object_pid);
+
+	command_close_bidi_pipe($_hash_object_pid, $_hash_object_in, $_hash_object_out, $_hash_object_ctx);
+}
+
+sub hash_object {
+	my (undef, $fh) = @_;
+
+	my ($tmp_fh, $tmp_filename) = tempfile(UNLINK => 1);
+	while (my $line = <$fh>) {
+		print $tmp_fh $line;
+	}
+	close($tmp_fh);
+	_open_hash_object_if_needed();
+	print $_hash_object_out $tmp_filename . "\n";
+	chomp(my $hash = <$_hash_object_in>);
+	return $hash;
+}
+
 __END__
 
 Data structures:
-- 
1.5.3.4.1333.ga2f32

^ permalink raw reply related

* [PATCH 8/9] Git.pm: Add command_bidi_pipe and command_close_bidi_pipe
From: Adam Roben @ 2007-10-23  5:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Adam Roben, Petr Baudis
In-Reply-To: <1193118397-4696-8-git-send-email-aroben@apple.com>

command_bidi_pipe hands back the stdin and stdout file handles from the
executed command. command_close_bidi_pipe closes these handles and terminates
the process.

Signed-off-by: Adam Roben <aroben@apple.com>
---
 perl/Git.pm |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/perl/Git.pm b/perl/Git.pm
index 3f4080c..eb699ff 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -51,6 +51,7 @@ require Exporter;
 # Methods which can be called as standalone functions as well:
 @EXPORT_OK = qw(command command_oneline command_noisy
                 command_output_pipe command_input_pipe command_close_pipe
+                command_bidi_pipe command_close_bidi_pipe
                 version exec_path hash_object git_cmd_try);
 
 
@@ -92,6 +93,7 @@ increate nonwithstanding).
 use Carp qw(carp croak); # but croak is bad - throw instead
 use Error qw(:try);
 use Cwd qw(abs_path);
+use IPC::Open2 qw(open2);
 
 }
 
@@ -375,6 +377,60 @@ sub command_close_pipe {
 	_cmd_close($fh, $ctx);
 }
 
+=item command_bidi_pipe ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given C<COMMAND> in the same way as command_output_pipe()
+does but return both an input pipe filehandle and an output pipe filehandle.
+
+The function will return return C<($pid, $pipe_in, $pipe_out, $ctx)>.
+See C<command_close_bidi_pipe()> for details.
+
+=cut
+
+sub command_bidi_pipe {
+	my ($pid, $in, $out);
+	$pid = open2($in, $out, @_);
+	return ($pid, $in, $out, join(' ', @_));
+}
+
+=item command_close_bidi_pipe ( PID, PIPE_IN, PIPE_OUT [, CTX] )
+
+Close the C<PIPE_IN> and C<PIPE_OUT> as returned from C<command_bidi_pipe()>,
+checking whether the command finished successfully. The optional C<CTX>
+argument is required if you want to see the command name in the error message,
+and it is the fourth value returned by C<command_bidi_pipe()>.  The call idiom
+is:
+
+	my ($pid, $in, $out, $ctx) = $r->command_bidi_pipe('cat-file --stdin');
+	print "000000000\n" $out;
+	while (<$in>) { ... }
+	$r->command_close_bidi_pipe($pid, $in, $out, $ctx);
+
+Note that you should not rely on whatever actually is in C<CTX>;
+currently it is simply the command name but in future the context might
+have more complicated structure.
+
+=cut
+
+sub command_close_bidi_pipe {
+	my ($pid, $in, $out, $ctx) = @_;
+	foreach my $fh ($in, $out) {
+		if (not close $fh) {
+			if ($!) {
+				carp "error closing pipe: $!";
+			} elsif ($? >> 8) {
+				throw Git::Error::Command($ctx, $? >>8);
+			}
+		}
+	}
+
+	waitpid $pid, 0;
+
+	if ($? >> 8) {
+		throw Git::Error::Command($ctx, $? >>8);
+	}
+}
+
 
 =item command_noisy ( COMMAND [, ARGUMENTS... ] )
 
-- 
1.5.3.4.1333.ga2f32

^ permalink raw reply related

* Re: [PATCH 7/9] git-hash-object: Add --stdin-paths option
From: Shawn O. Pearce @ 2007-10-23  5:53 UTC (permalink / raw)
  To: Adam Roben; +Cc: git, Junio C Hamano
In-Reply-To: <1193118397-4696-8-git-send-email-aroben@apple.com>

Adam Roben <aroben@apple.com> wrote:
> This allows multiple paths to be specified on stdin.

git-fast-import wasn't suited to the task?
 
-- 
Shawn.

^ permalink raw reply

* Re: [PATCH 7/9] git-hash-object: Add --stdin-paths option
From: Adam Roben @ 2007-10-23  5:57 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git, Junio C Hamano
In-Reply-To: <20071023055331.GF14735@spearce.org>

Shawn O. Pearce wrote:
> Adam Roben <aroben@apple.com> wrote:
>   
>> This allows multiple paths to be specified on stdin.
>>     
>
> git-fast-import wasn't suited to the task?
>   

I actually considered using fast-import for the whole shebang, but 
decided that I don't yet understand the workings and structure of 
git-svn well enough to make such a big change.

git-svn uses git-hash-object to both determine a file's hash and insert 
it into the index in one go -- can fast-import do this? Or will it just 
put it in the index and not give you the hash back? The latter was my 
impression.

-Adam

^ permalink raw reply

* Re: [PATCH 0/9] Make git-svn fetch ~1.7x faster
From: Mike Hommey @ 2007-10-23  6:08 UTC (permalink / raw)
  To: Adam Roben; +Cc: git, Junio C Hamano
In-Reply-To: <1193118397-4696-1-git-send-email-aroben@apple.com>

On Mon, Oct 22, 2007 at 10:46:28PM -0700, Adam Roben wrote:
> 
> This patch series makes git-svn fetch about 1.7x faster by reducing the number
> of forks/execs that occur for each file retrieved from Subversion. To do so, a
> few new options are added to git-cat-file and git-hash-object to allow
> continuous input on stdin and continuous output on stdout, so that one instance
> of each of these commands can be kept running for the duration of the fetch.

You don't need to do this to avoid forks. Just use git-fast-import
instead.

Mike

^ permalink raw reply

* Re: [PATCH 7/9] git-hash-object: Add --stdin-paths option
From: Shawn O. Pearce @ 2007-10-23  6:10 UTC (permalink / raw)
  To: Adam Roben; +Cc: git, Junio C Hamano
In-Reply-To: <471D8D34.4050104@apple.com>

Adam Roben <aroben@apple.com> wrote:
> Shawn O. Pearce wrote:
> >Adam Roben <aroben@apple.com> wrote:
> >  
> >>This allows multiple paths to be specified on stdin.
> >
> >git-fast-import wasn't suited to the task?
> 
> I actually considered using fast-import for the whole shebang, but 
> decided that I don't yet understand the workings and structure of 
> git-svn well enough to make such a big change.
> 
> git-svn uses git-hash-object to both determine a file's hash and insert 
> it into the index in one go -- can fast-import do this? Or will it just 
> put it in the index and not give you the hash back? The latter was my 
> impression.

It doesn't currently give you the hash back.  You can sort of get
to it by marking the blob then using the 'checkpoint' command to
dump the marks to a file, which you can read in.  Not good.

It probably wouldn't be very difficult to give fast-import a way
to dump marks back on stdout as they are assigned.  So long as the
frontend either locksteps with fast-import or is willing to monitor
it with a select/poll type of arrangement and read from stdout as
soon as its ready.

Probably a 5 line code change to fast-import.  Like this.  Only Git
won't recognize that object SHA-1 as its in a packfile that has
no index.  You'd need to 'checkpoint' to flush the object out, or
just use all of fast-import for the processing.  So yea, I guess
I can see now how its not suited to this.


--8>--
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index d511967..7fd8b2c 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -67,6 +67,10 @@ OPTIONS
 	at checkpoint (or completion) the same path can also be
 	safely given to \--import-marks.
 
+--export-marks-to-stdout::
+	Dumps marks to stdout as soon as they are assigned.
+	Marks are written one per line as `:markid SHA-1`.
+
 --import-marks=<file>::
 	Before processing any input, load the marks specified in
 	<file>.  The input file must exist, must be readable, and
diff --git a/fast-import.c b/fast-import.c
index 6f888f6..619ed05 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -272,6 +272,7 @@ struct recent_command
 static unsigned long max_depth = 10;
 static off_t max_packsize = (1LL << 32) - 1;
 static int force_update;
+static int marks_to_stdout;
 
 /* Stats and misc. counters */
 static uintmax_t alloc_count;
@@ -561,6 +562,7 @@ static char *pool_strdup(const char *s)
 
 static void insert_mark(uintmax_t idnum, struct object_entry *oe)
 {
+	uintmax_t orig_idnum = idnum;
 	struct mark_set *s = marks;
 	while ((idnum >> s->shift) >= 1024) {
 		s = pool_calloc(1, sizeof(struct mark_set));
@@ -580,6 +582,8 @@ static void insert_mark(uintmax_t idnum, struct object_entry *oe)
 	if (!s->data.marked[idnum])
 		marks_set_count++;
 	s->data.marked[idnum] = oe;
+	if (marks_to_stdout)
+		printf(":%" PRIuMAX " %s\n", orig_idnum, sha1_to_hex(oe->sha1));
 }
 
 static struct object_entry *find_mark(uintmax_t idnum)
@@ -2294,6 +2298,8 @@ int main(int argc, const char **argv)
 			max_active_branches = strtoul(a + 18, NULL, 0);
 		else if (!prefixcmp(a, "--import-marks="))
 			import_marks(a + 15);
+		else if (!prefixcmp(a, "--export-marks-to-stdout"))
+			marks_to_stdout = 1;
 		else if (!prefixcmp(a, "--export-marks="))
 			mark_file = a + 15;
 		else if (!prefixcmp(a, "--export-pack-edges=")) {

-- 
Shawn.

^ permalink raw reply related

* Re: [PATCH 0/9] Make git-svn fetch ~1.7x faster
From: Adam Roben @ 2007-10-23  6:13 UTC (permalink / raw)
  To: Mike Hommey; +Cc: git, Junio C Hamano
In-Reply-To: <20071023060812.GA30978@glandium.org>

Mike Hommey wrote:
> On Mon, Oct 22, 2007 at 10:46:28PM -0700, Adam Roben wrote:
>   
>> This patch series makes git-svn fetch about 1.7x faster by reducing the number
>> of forks/execs that occur for each file retrieved from Subversion. To do so, a
>> few new options are added to git-cat-file and git-hash-object to allow
>> continuous input on stdin and continuous output on stdout, so that one instance
>> of each of these commands can be kept running for the duration of the fetch.
>>     
>
> You don't need to do this to avoid forks. Just use git-fast-import
> instead.
>   


I agree that fast-import is probably ultimately a better solution for 
this, but given that git-svn currently uses the output of every command 
it forks off and that fast-import doesn't seem to give the same output, 
changing git-svn to use fast-import would be a fairly sweeping change 
that I didn't feel comfortable making without a better understanding of 
git-svn.

-Adam

^ permalink raw reply

* Re: [PATCH] use only the PATH for exec'ing git commands
From: Johannes Sixt @ 2007-10-23  6:14 UTC (permalink / raw)
  To: srp; +Cc: Alex Riesen, git
In-Reply-To: <1193091122.v2.fusewebmail-240137@f>

Scott R Parish schrieb:
>> Alex Riesen, Mon, Oct 22, 2007 12:01
>> Scott R Parish, Mon, Oct 22, 2007 19:01:48 +0200:
>>> +                strbuf_addch(out, ':');
>> Shouldn't it break MingW32 native port?
> 
> What can i do here to better accommodate MingW32? You're
> right, just because the original code did it this way
> isn't a good excuse for me not to do it better.

Don't bother with it right now. GIT currently does not have MinGW specific 
code, yet.

-- Hannes

^ permalink raw reply

* Re: [PATCH 1/2] Added basic color support to git add --interactive
From: Wincent Colaiuta @ 2007-10-23  6:28 UTC (permalink / raw)
  To: Jeff King
  Cc: Dan Zwell, Shawn O. Pearce, Git Mailing List,
	Jonathan del Strother, Johannes Schindelin, Frank Lichtenheld
In-Reply-To: <20071023040315.GA28312@coredump.intra.peff.net>

El 23/10/2007, a las 6:03, Jeff King escribió:

> This does nothing for embedded newlines in the strings, which means  
> that
> you can end up with ${COLOR}text\n${RESET}, which fouls up changed
> backgrounds. See commit 50f575fc. Since the strings you are  
> printing are
> small, I don't see any problem with making a copy, using a regex to
> insert the color coding, and printing that (I think I even posted
> example code in a previous thread on this subject).

I did too, where you add a third, optional "trailer" parameter to the  
function where you pass the newline if there is one (following the  
style of the functions in color.c). Pasting it below.

Having said that, I think this kind of function belongs in Git.pm,  
and the dependency on Term::ANSIColor should be replaced with  
dependency-free code that generates the colors itself; this should be  
easy because the number of possible colors is small, Git thus far  
only uses a subset of the possible ANSI colors, and the C code for  
doing it is already there in color.c and just needs to be translated  
into Perl.

sub print_ansi_color {
	my $color = shift;
	my $string = shift;
	my $trailer = shift;
	if ($use_color) {
		print Term::ANSIColor::color($color), $string,
		    Term::ANSIColor::color('clear');
	} else {
		print $string;
	}
	if ($trailer) {
		print $trailer;
	}
}

Cheers,
Wincent

^ permalink raw reply

* Re: [PATCH] Add some fancy colors in the test library when terminal supports it.
From: Johannes Sixt @ 2007-10-23  6:37 UTC (permalink / raw)
  To: Christian Couder; +Cc: Pierre Habouzit, Shawn O. Pearce, git
In-Reply-To: <200710230608.15124.chriscool@tuxfamily.org>

Christian Couder schrieb:
> Anyway, perhaps having:
> 
> _red=1
> _green=2
> 
> and then using "say_color $_red stuff" might be easier to understand and 
> change if needed.

Good idea. But then better name it by its purpose:

fail=1	# red
pass=2	# green

-- Hannes

^ permalink raw reply

* Re: [PATCH 1/2] Added basic color support to git add --interactive
From: Jeff King @ 2007-10-23  6:41 UTC (permalink / raw)
  To: Wincent Colaiuta
  Cc: Dan Zwell, Shawn O. Pearce, Git Mailing List,
	Jonathan del Strother, Johannes Schindelin, Frank Lichtenheld
In-Reply-To: <D1795135-AD5E-491C-99E6-30486E189B13@wincent.com>

On Tue, Oct 23, 2007 at 08:28:28AM +0200, Wincent Colaiuta wrote:

> I did too, where you add a third, optional "trailer" parameter to the 
> function where you pass the newline if there is one (following the style of 
> the functions in color.c). Pasting it below.

The problem with that approach is that you can only send in a single
line at a time (with the newline detached!), so it makes life harder for
the caller. E.g., there is at least one spot that uses a here-doc with
many lines; splitting that into a bunch of print_ansi_color calls would
be unnecessarily ugly.

> Having said that, I think this kind of function belongs in Git.pm, and the 

Yes! Most of this is obviously library-ish code, and should go into the
library.

> dependency on Term::ANSIColor should be replaced with dependency-free code 
> that generates the colors itself; this should be easy because the number of 

Out of curiosity, are people really running perl < 5.6?  Term::ANSIColor
has been in the base distribution for 7 years now.

-Peff

^ permalink raw reply

* Re: [PATCH 1/9] Add tests for git cat-file
From: Johannes Sixt @ 2007-10-23  6:59 UTC (permalink / raw)
  To: Adam Roben; +Cc: git, Junio C Hamano
In-Reply-To: <1193118397-4696-2-git-send-email-aroben@apple.com>

Adam Roben schrieb:
> +    test_expect_success \
> +        "$type exists" \
> +        "git cat-file -e $hello_sha1"

You mean $sha1 here, right?

> +    test_expect_success \
> +        "Type of $type is correct" \
> +        "test $type = \"$(git cat-file -t $sha1)\""

This should escape the $(...) in all the tests. Like this:

         "test $type = \"\$(git cat-file -t $sha1)\""

> +test_expect_success \
> +    "Reach a blob from a tag pointing to it" \
> +    "test \"$hello_content\" = \"$(git cat-file blob $tag_sha1)\""

And use single quotes without escaping the double-quotes here.

-- Hannes

^ permalink raw reply

* Re: [PATCH 6/9] Add tests for git hash-object
From: Johannes Sixt @ 2007-10-23  6:59 UTC (permalink / raw)
  To: Adam Roben; +Cc: git, Junio C Hamano
In-Reply-To: <1193118397-4696-7-git-send-email-aroben@apple.com>

Adam Roben schrieb:
> +test_expect_success \
> +    'hash a file' \
> +    "test $hello_sha1 = $(git hash-object hello)"

Put tests in double-quotes; otherwise, the substitutions happen before the 
test begins, and not as part of the test.

-- Hannes

^ permalink raw reply

* Re: [PATCH 9/9] git-svn: Make fetch ~1.7x faster
From: Johannes Sixt @ 2007-10-23  7:01 UTC (permalink / raw)
  To: Adam Roben; +Cc: git, Junio C Hamano, Eric Wong
In-Reply-To: <1193118397-4696-10-git-send-email-aroben@apple.com>

Adam Roben schrieb:
> We were spending a lot of time forking/execing git-cat-file and
> git-hash-object. We now use command_bidi_pipe to keep one instance of each
> running and feed it input on stdin.

I appreciate this. It's certainly going to be a much bigger win on Windows, 
although git svn doesn't work (in the MinGW port) at this time because of 
the old perl and the missing SVN module.

-- Hannes

^ permalink raw reply

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Andreas Ericsson @ 2007-10-23  7:24 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Johannes Schindelin, Steffen Prohaska, Federico Mena Quintero,
	git
In-Reply-To: <8fe92b430710221635x752c561ejcee14e2526010cc9@mail.gmail.com>

Jakub Narebski wrote:
> On 10/22/07, Andreas Ericsson <ae@op5.se> wrote:
>> Johannes Schindelin wrote:
>>> On Mon, 22 Oct 2007, Andreas Ericsson wrote:
>>>
>>>> If I were to suggest any improvements, it'd be to change the semantics of
>>>> git-pull to always update the local branches set up to be merged with the
>>>> remote tracking branches when they, prior to fetching, pointed to the same
>>>> commit, such that when
>>>>
>>>> $ git show-ref master
>>>> d4027a816dd0b416dc8c7b37e2c260e6905f11b6 refs/heads/master
>>>> d4027a816dd0b416dc8c7b37e2c260e6905f11b6 refs/remotes/origin/master
>>>>
>>>> refs/heads/master gets set to refs/remotes/origin/master post-fetch.
>>> In general, this should fail.  Because you are expected to have local
>>> changes in the local branches.
>>
>> BS argument. Git knows when I haven't got any changes on my local
>> branches, and it can be fairly safely assumed that when I feel like
>> making any, I'd like to make them off as fresh a tip as possible unless
>> I explicitly tell git otherwise.
> [cut]
> 
> It would be I think possible to make git behave as you want, although I'd rather
> (at least at first) have behaviour described above turned on by some option
> or config variable. I guess that it would be not that hard to make script to do
> what you ant (and probably it would be best if you tried your idea that way).
> 
> There are the following caveats.
> 1. For each local branch that is to be updated on pull, this branch
> must be marked as tracking some branch of some repository. This has to
> be explicitely done; for example by creating those branches using
> --track option.
> 2. Git can do a merge with conflicts _only_ if that branch is checked
> out. So for all local branches which you want to get updated using
> "git pull --update-all <repo>" (or something like that), the merge
> with remote branch should be either fast-forward, trivial merge, or
> merge without conflicts. "git pull --update-all <repo>" would return
> then list of updated branches and list of branches which cannot be
> updated.
> 
> So... are you going to try to implement that?

Yes, but only for fast-forward cases. When there *are* local changes, 
the user must decide when to merge those, since he/she may not be done 
with them. It doesn't make sense to merge local canges on a not checked 
out branch automagically, because then we end up in the very unclear 
semantics that Dscho (and myself) fear.

Also, as Steffen pointed out in his mail, this will make "git pull" 
largely symmetrical with "git push", which *does* update all the remote 
branches, but only if the update results in a fast-forward.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* Re: [PATCH 1/2] Added basic color support to git add --interactive
From: Wincent Colaiuta @ 2007-10-23  7:44 UTC (permalink / raw)
  To: Jeff King
  Cc: Dan Zwell, Shawn O. Pearce, Git Mailing List,
	Jonathan del Strother, Johannes Schindelin, Frank Lichtenheld
In-Reply-To: <20071023064106.GA30351@coredump.intra.peff.net>

El 23/10/2007, a las 8:41, Jeff King escribió:

> On Tue, Oct 23, 2007 at 08:28:28AM +0200, Wincent Colaiuta wrote:
>
>> I did too, where you add a third, optional "trailer" parameter to the
>> function where you pass the newline if there is one (following the  
>> style of
>> the functions in color.c). Pasting it below.
>
> The problem with that approach is that you can only send in a single
> line at a time (with the newline detached!), so it makes life  
> harder for
> the caller. E.g., there is at least one spot that uses a here-doc with
> many lines; splitting that into a bunch of print_ansi_color calls  
> would
> be unnecessarily ugly.

Yes, I agree that it complicates things for the caller. I was just  
copying the model found in color.c; but seeing as this is Perl  
splitting into lines inside the printing function would be  
straightforward.

Cheers,
Wincent

^ permalink raw reply

* Re: [PATCH] Add some fancy colors in the test library when terminal supports it.
From: Pierre Habouzit @ 2007-10-23  8:13 UTC (permalink / raw)
  To: Christian Couder; +Cc: Shawn O. Pearce, git
In-Reply-To: <200710230608.15124.chriscool@tuxfamily.org>

[-- Attachment #1: Type: text/plain, Size: 1223 bytes --]

On Tue, Oct 23, 2007 at 04:08:14AM +0000, Christian Couder wrote:
> Hi Pierre,
> 
> Le lundi 22 octobre 2007, Pierre Habouzit a écrit :
> > +
> > +say_color () {
> > +	[ "$nocolor" = 0 ] &&  [ "$1" != '-1' ] && tput setaf "$1"
> > +	shift
> > +	echo "* $*"
> > +	tput op
> > +}
> > +
> >  error () {
> > -	echo "* error: $*"
> > +	say_color 9 "* error: $*"
> 
> This will print something like "* * error: ..." instead of "* error: ..."
> 
> The following should work:
> 
> > +	say_color 9 "error: $*"
> 
> By the way, where do the 9 here and the 10 and the -1 below come from ?
> "man 5 terminfo" says that only values form 0 to 7 are portably defined.
> Maybe 9 is a bold red and 10 a bold green, or something like that, but it 
> doesn't seem to work on my konsole.

Right I should use tput setb or sth like that to ask for bold mode
probably.

> Anyway, perhaps having:
> 
> _red=1
> _green=2
> 
> and then using "say_color $_red stuff" might be easier to understand and 
> change if needed.

Agreed.

-- 
·O·  Pierre Habouzit
··O                                                madcoder@debian.org
OOO                                                http://www.madism.org

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [RFC/PATCH] git-fetch: mega-terse fetch output
From: Miles Bader @ 2007-10-23  8:39 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Santi Béjar, Shawn O. Pearce, David Symonds, Jeff King, git
In-Reply-To: <alpine.LFD.0.9999.0710190913280.19446@xanadu.home>

Nicolas Pitre <nico@cam.org> writes:
> I think the advantage of having only one line of output per branch 
> really outweight the need for old..new notation.  Do you really benefit 
> from it?

The "one-line" issue has already been resolved in other messages, but I
just wanted to say I use this info all the time.

-Miles

-- 
"Suppose He doesn't give a shit?  Suppose there is a God but He
just doesn't give a shit?"  [George Carlin]

^ permalink raw reply

* Re: [PATCH 2/2] Let git-add--interactive read colors from git-config
From: Dan Zwell @ 2007-10-23  8:52 UTC (permalink / raw)
  To: Jeff King
  Cc: Shawn O. Pearce, Wincent Colaiuta, Git Mailing List,
	Jonathan del Strother, Johannes Schindelin, Frank Lichtenheld
In-Reply-To: <20071023042702.GB28312@coredump.intra.peff.net>

On Tue, 23 Oct 2007 00:27:02 -0400
Jeff King <peff@peff.net> wrote:

> On Mon, Oct 22, 2007 at 04:40:48PM -0500, Dan Zwell wrote:
> 
> > Note: the code to parse git-style color strings to perl-style color
> > strings should eventually be added to Git.pm so that other (perl)
> > parts of git can be configured to read colors from .gitconfig in
> > a nicer way. A git-style string is "ul red black", while perl 
> > likes strings like "underline red on_black".
> 
> Why not do it as part of this patch, then?
Will do. I didn't include it in the patch because I need to learn more
about perl before I can make this change, though I can probably just
find enough examples in the other scripts that use Git.pm.

> 
> > +	# Sane (visible) defaults:
> > +	if (! @git_prompt_color) {
> > +		@git_prompt_color = ("blue", "bold");
> > +	}
> 
> I think it might be a bit more readable to keep the assignment and
> defaults together:
> 
>   my @git_prompt_color = split /\s+/,
>     qx(git config --get color.interactive.prompt) || 'blue bold';
> 
> Though I wonder why we are splitting here at all, since we just end up
> converting the list into a scalar below. And if we just turned that
> into a function, we could get a nice:
> 
>   my $prompt_color = git_color_to_ansicolor(
>     qx(git config --get color.interactive.prompt) || 'blue bold');
I agree, now that you mention it. Eventually the string must be split
(parsing it left to right by word makes more sense than trying to
mutate it with regular expressions, if only because it's a lot harder
to make mistakes), but there's no reason not to split the string inside
the loop, where it would look nicer/more contained. I will make this
change.

Dan

^ permalink raw reply

* Re: stash clear, was Re: git: avoiding merges, rebasing
From: Miles Bader @ 2007-10-23  8:55 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Eric Blake, bug-gnulib, Bruno Haible, git
In-Reply-To: <Pine.LNX.4.64.0710191533490.16728@wbgn129.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> Instead, how about writing a stash pop?  "git stash pop [<stash>]".  It 
> would literally just call git stash apply && git reflog delete.  Should 
> not be too difficult, now that I provided "git reflog delete" ;-)
>
> Maybe even deprecating "git stash clear", or doing away with it 
> altogether.

That would match my usual usage well.

Actually, I really like the way the tla (arch) "undo" and "redo"
commands work:  "tla undo" is roughly equivalent to "git stash", but by
default chooses a name with an appended integer which is one greater
than the greatest existing "stash" (to use git terminology).  "tla redo"
by default applies the last saved value and deletes it.  So basically
push and pop.  Usually, of course, you only use one level, but on the
occasions when you want more, it feels very natural.

I dunno how this would work with stash, but push/pop functionality would
be good...

-Miles

-- 
Saa, shall we dance?  (from a dance-class advertisement)

^ permalink raw reply

* Re: gitk still interested in translations?
From: Paul Mackerras @ 2007-10-23 10:17 UTC (permalink / raw)
  To: Christian Stimming; +Cc: git, Junio C Hamano
In-Reply-To: <200710211454.23143.stimming@tuhh.de>

Christian Stimming writes:

> What is the progress on your i18n plans in gitk? None of the patches had been 
> applied to gitk, have they? If you say you *are* interested, I'd be happy to 
> provide an up-to-date patch against gitk.git @ kernel.org for #1 Makefile 
> rules, #2 msgcat integration, and most importantly #3 message markup.

No, I haven't put in any of the i18n stuff.  I would certainly be
interested in seeing the patches, and I will probably apply them.

What was the resolution about where to install the mesesage catalogs?

Regards,
Paul.

^ permalink raw reply

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Johannes Schindelin @ 2007-10-23 10:58 UTC (permalink / raw)
  To: Steffen Prohaska
  Cc: Jakub Narebski, Andreas Ericsson, Federico Mena Quintero, git
In-Reply-To: <92320AA3-6D23-4967-818D-F7FA3962E88D@zib.de>

Hi,

On Tue, 23 Oct 2007, Steffen Prohaska wrote:

> 
> On Oct 23, 2007, at 1:35 AM, Jakub Narebski wrote:
> 
> > 2. Git can do a merge with conflicts _only_ if that branch is checked 
> > out.
> 
> Andreas' proposal contains an important requirement that avoids this 
> problem. His proposal states "when they, prior to fetching, pointed to 
> the same commit [the head in remotes pointed to]". That is only 
> fast-forwards are needed, which never have merge conflicts.

You know what I do not like with this proposal?  The whole _point_ of this 
discussion is to make git _easier_.  Go ahead, try to explain to a 
complete git newbie the proposed behaviour.  I have a pound here which 
says that there is _no_ _way_ that this newbie says "well, that's easy".

Some people may not get this, but git has a reputation of being 
complicated, and my "BS" argument was, is, and will be, that we should 
keep clear and simple semantics, because they are the _only_ way to battle 
that reputation.

Ciao,
Dscho

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox