Git development
 help / color / mirror / Atom feed
* 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 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

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

* [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 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 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 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 4/9] git-cat-file: Add --stdin 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-4-git-send-email-aroben@apple.com>

This lets you specify object names on stdin instead of on the command line.

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

diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt
index afa095c..588d71a 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>] <object>
+'git-cat-file' [-t | -s | -e | -p | <type>] [--stdin | <object>]
 
 DESCRIPTION
 -----------
@@ -23,6 +23,10 @@ OPTIONS
 	For a more complete list of ways to spell object names, see
 	"SPECIFYING REVISIONS" section in gitlink:git-rev-parse[1].
 
+--stdin::
+	Read object names from stdin instead of specifying one on the
+	command line.
+
 -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 3a0be4a..0f1ffe5 100644
--- a/builtin-cat-file.c
+++ b/builtin-cat-file.c
@@ -143,12 +143,14 @@ 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>] <sha1>";
+static const char cat_file_usage[] = "git-cat-file [-t|-s|-e|-p|<type>] [--stdin | <sha1>]";
 
 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;
 
 	git_config(git_default_config);
 
@@ -161,6 +163,11 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
 			continue;
 		}
 
+		if (!strcmp(arg, "--stdin")) {
+		    read_stdin = 1;
+		    continue;
+		}
+
 		if (arg[0] == '-')
 			usage(cat_file_usage);
 
@@ -169,15 +176,26 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
 			continue;
 		}
 
-		if (obj_name)
+		if (obj_name || read_stdin)
 			usage(cat_file_usage);
 
 		obj_name = arg;
 		break;
 	}
 
-	if (!exp_type || !obj_name)
+	if (!read_stdin) {
+	    if (!exp_type || !obj_name)
 		usage(cat_file_usage);
+	    return cat_one_file(opt, exp_type, obj_name);
+	}
 
-	return cat_one_file(opt, exp_type, obj_name);
+	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;
+	}
+	strbuf_release(&buf);
+
+	return 0;
 }
diff --git a/t/t1005-cat-file.sh b/t/t1005-cat-file.sh
index 2fdc446..49eb89d 100755
--- a/t/t1005-cat-file.sh
+++ b/t/t1005-cat-file.sh
@@ -88,4 +88,18 @@ test_expect_success \
     "Reach a blob from a tag pointing to it" \
     "test \"$hello_content\" = \"$(git cat-file blob $tag_sha1)\""
 
+sha1s="$hello_sha1
+$tree_sha1
+$commit_sha1
+$tag_sha1"
+
+sizes="$hello_size
+$tree_size
+$commit_size
+$tag_size"
+
+test_expect_success \
+    "Pass object hashes on stdin" \
+    "test \"$sizes\" = \"$(echo "$sha1s" | git cat-file -s --stdin)\""
+
 test_done
-- 
1.5.3.4.1333.ga2f32

^ permalink raw reply related

* [PATCH 2/9] git-cat-file: Small refactor of cmd_cat_file
From: Adam Roben @ 2007-10-23  5:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Adam Roben
In-Reply-To: <1193118397-4696-2-git-send-email-aroben@apple.com>

I separated the logic of parsing the arguments from the logic of fetching and
outputting the data. cat_one_file now does the latter.

Signed-off-by: Adam Roben <aroben@apple.com>
---
 builtin-cat-file.c |   38 ++++++++++++++++++++++----------------
 1 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/builtin-cat-file.c b/builtin-cat-file.c
index f132d58..34a63d1 100644
--- a/builtin-cat-file.c
+++ b/builtin-cat-file.c
@@ -76,31 +76,16 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
 		write_or_die(1, cp, endp - cp);
 }
 
-int cmd_cat_file(int argc, const char **argv, const char *prefix)
+static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
 {
 	unsigned char sha1[20];
 	enum object_type type;
 	void *buf;
 	unsigned long size;
-	int opt;
-	const char *exp_type, *obj_name;
-
-	git_config(git_default_config);
-	if (argc != 3)
-		usage("git-cat-file [-t|-s|-e|-p|<type>] <sha1>");
-	exp_type = argv[1];
-	obj_name = argv[2];
 
 	if (get_sha1(obj_name, sha1))
 		die("Not a valid object name %s", obj_name);
 
-	opt = 0;
-	if ( exp_type[0] == '-' ) {
-		opt = exp_type[1];
-		if ( !opt || exp_type[2] )
-			opt = -1; /* Not a single character option */
-	}
-
 	buf = NULL;
 	switch (opt) {
 	case 't':
@@ -157,3 +142,24 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
 	write_or_die(1, buf, size);
 	return 0;
 }
+
+int cmd_cat_file(int argc, const char **argv, const char *prefix)
+{
+	int opt;
+	const char *exp_type, *obj_name;
+
+	git_config(git_default_config);
+	if (argc != 3)
+		usage("git-cat-file [-t|-s|-e|-p|<type>] <sha1>");
+	exp_type = argv[1];
+	obj_name = argv[2];
+
+	opt = 0;
+	if ( exp_type[0] == '-' ) {
+		opt = exp_type[1];
+		if ( !opt || exp_type[2] )
+			opt = -1; /* Not a single character option */
+	}
+
+	return cat_one_file(opt, exp_type, obj_name);
+}
-- 
1.5.3.4.1333.ga2f32

^ permalink raw reply related

* [PATCH 3/9] git-cat-file: Make option parsing a little more flexible
From: Adam Roben @ 2007-10-23  5:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Adam Roben
In-Reply-To: <1193118397-4696-3-git-send-email-aroben@apple.com>

This will make it easier to add newer options later.

Signed-off-by: Adam Roben <aroben@apple.com>
---
 builtin-cat-file.c |   42 ++++++++++++++++++++++++++++++------------
 1 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/builtin-cat-file.c b/builtin-cat-file.c
index 34a63d1..3a0be4a 100644
--- a/builtin-cat-file.c
+++ b/builtin-cat-file.c
@@ -143,23 +143,41 @@ 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>] <sha1>";
+
 int cmd_cat_file(int argc, const char **argv, const char *prefix)
 {
-	int opt;
-	const char *exp_type, *obj_name;
+	int i, opt = 0;
+	const char *exp_type = 0, *obj_name = 0;
 
 	git_config(git_default_config);
-	if (argc != 3)
-		usage("git-cat-file [-t|-s|-e|-p|<type>] <sha1>");
-	exp_type = argv[1];
-	obj_name = argv[2];
-
-	opt = 0;
-	if ( exp_type[0] == '-' ) {
-		opt = exp_type[1];
-		if ( !opt || exp_type[2] )
-			opt = -1; /* Not a single character option */
+
+	for (i = 1; i < argc; ++i) {
+		const char *arg = argv[i];
+
+		if (!strcmp(arg, "-t") || !strcmp(arg, "-s") || !strcmp(arg, "-e") || !strcmp(arg, "-p")) {
+			exp_type = arg;
+			opt = exp_type[1];
+			continue;
+		}
+
+		if (arg[0] == '-')
+			usage(cat_file_usage);
+
+		if (!exp_type) {
+			exp_type = arg;
+			continue;
+		}
+
+		if (obj_name)
+			usage(cat_file_usage);
+
+		obj_name = arg;
+		break;
 	}
 
+	if (!exp_type || !obj_name)
+		usage(cat_file_usage);
+
 	return cat_one_file(opt, exp_type, obj_name);
 }
-- 
1.5.3.4.1333.ga2f32

^ permalink raw reply related

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


Signed-off-by: Adam Roben <aroben@apple.com>
---
 t/t1005-cat-file.sh |   91 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 91 insertions(+), 0 deletions(-)
 create mode 100755 t/t1005-cat-file.sh

diff --git a/t/t1005-cat-file.sh b/t/t1005-cat-file.sh
new file mode 100755
index 0000000..2fdc446
--- /dev/null
+++ b/t/t1005-cat-file.sh
@@ -0,0 +1,91 @@
+#!/bin/sh
+
+test_description='git cat-file'
+
+. ./test-lib.sh
+
+function maybe_remove_timestamp()
+{
+    if test -z "$2"; then
+        echo "$1"
+    else
+        echo "$1" | sed -e 's/ [0-9]\{10\} [+-][0-9]\{4\}$//'
+    fi
+}
+
+function run_tests()
+{
+    type=$1
+    sha1=$2
+    size=$3
+    content=$4
+    pretty_content=$5
+    no_timestamp=$6
+
+    test_expect_success \
+        "$type exists" \
+        "git cat-file -e $hello_sha1"
+    test_expect_success \
+        "Type of $type is correct" \
+        "test $type = \"$(git cat-file -t $sha1)\""
+    test_expect_success \
+        "Size of $type is correct" \
+        "test $size = \"$(git cat-file -s $sha1)\""
+    test -z "$content" || test_expect_success \
+        "Content of $type is correct" \
+        "test \"$(maybe_remove_timestamp "$content" $no_timestamp)\" = \"$(maybe_remove_timestamp "$(git cat-file $type $sha1)" $no_timestamp)\""
+    test_expect_success \
+        "Pretty content of $type is correct" \
+        "test \"$(maybe_remove_timestamp "$pretty_content" $no_timestamp)\" = \"$(maybe_remove_timestamp "$(git cat-file -p $sha1)" $no_timestamp)\""
+}
+
+hello_content="Hello World"
+hello_size=$(echo "$hello_content" | wc -c)
+hello_sha1=557db03de997c86a4a028e1ebd3a1ceb225be238
+
+echo "$hello_content" > hello
+
+git update-index --add hello
+
+run_tests 'blob' $hello_sha1 $hello_size "$hello_content" "$hello_content"
+
+tree_sha1=$(git write-tree)
+tree_size=33
+tree_pretty_content="100644 blob $hello_sha1	hello"
+
+run_tests 'tree' $tree_sha1 $tree_size "" "$tree_pretty_content"
+
+commit_message="Intial commit"
+commit_sha1=$(echo "$commit_message" | git commit-tree $tree_sha1)
+commit_size=177
+commit_content="tree $tree_sha1
+author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 0000000000 +0000
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 0000000000 +0000
+
+$commit_message"
+
+run_tests 'commit' $commit_sha1 $commit_size "$commit_content" "$commit_content" 1
+
+tag_header="object $hello_sha1
+type blob
+tag hellotag
+tagger $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
+tag_description="This is a tag"
+tag_content="$tag_header
+
+$tag_description"
+tag_pretty_content="$tag_header
+Thu Jan 1 00:00:00 1970 +0000
+
+$tag_description"
+
+tag_sha1=$(echo "$tag_content" | git mktag)
+tag_size=$(echo "$tag_content" | wc -c)
+
+run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_pretty_content"
+
+test_expect_success \
+    "Reach a blob from a tag pointing to it" \
+    "test \"$hello_content\" = \"$(git cat-file blob $tag_sha1)\""
+
+test_done
-- 
1.5.3.4.1333.ga2f32

^ permalink raw reply related

* [PATCH 0/9] Make git-svn fetch ~1.7x faster
From: Adam Roben @ 2007-10-23  5:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano


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.

The series is based on top of next. I considered basing it on top of the
parse_options work since I touch the option parsing in these two commands, but
I didn't know how wise it would be to base a patch series on something in pu.

I tried to add some new tests for cat-file and hash-object to ensure that I
didn't break old behavior, but I'm not very experienced with the git test suite
and I'm sure my tests could use some improvement. This is the most invasive
change I've yet made to git, so comments are more than welcome.

-Adam

--
 Documentation/git-cat-file.txt    |   11 +++-
 Documentation/git-hash-object.txt |    5 +-
 builtin-cat-file.c                |   96 +++++++++++++++++++++----
 git-svn.perl                      |   94 +++++++++++++++++++------
 hash-object.c                     |   29 ++++++++-
 perl/Git.pm                       |   56 +++++++++++++++
 t/t1005-cat-file.sh               |  139 +++++++++++++++++++++++++++++++++++++
 t/t1006-hash-object.sh            |   49 +++++++++++++
 8 files changed, 438 insertions(+), 41 deletions(-)
--

^ permalink raw reply

* Re: What's cooking in git/spearce.git (topics)
From: Shawn O. Pearce @ 2007-10-23  5:42 UTC (permalink / raw)
  To: Theodore Tso; +Cc: Junio C Hamano, Johannes Schindelin, git
In-Reply-To: <20071023053003.GE27132@thunk.org>

Theodore Tso <tytso@mit.edu> wrote:
> On Tue, Oct 23, 2007 at 01:07:26AM -0400, Shawn O. Pearce wrote:
> > Junio has in the past proposed rewinding next, especially after a
> > significant release (e.g. 1.5.3).  
> 
> Hmm, yes.  I think I'd want to rewind next after a while; the thought
> of next drifting hundreds or thousands of commits away from master
> just gives me the heebee-jeebies.  I'm sure it mostly works, but it
> just feels wrong.  :-)

There's been a couple of times in git history where Junio has basically
done this to whack next back into line:

	git checkout next
	git diff next master | git apply --index
	git commit -m "Whack next back in line"

Because we've found a change or two lurking in there that shouldn't
have been there after a while.  I think it was related to a merge
conflict that happened in next but didn't in master or something
like that.  But usually this difference exists as there's usually
always something cooking in next.
 
> > A bunch of folks (myself included if I recall correctly) didn't want
> > to do this, as we create topic branches locally from things in next
> > and sometimes make commits over them to improve the topic further.
> 
> I guess I don't see why this would be a hardship; would a quick rebase
> on the topic branches more or less take care of the problem?  

Yes.  But you need the prior value of the branch so you can do
something easy like:

	git checkout yourtopic
	git rebase --onto $newtopic $oldtopic

which means you probably need to look through the logs for not just
pu but also pu@{1}.  A script to break out the topic branches from
pu post fetch and store them as proper tracking branches would make
this easier, but that much.  If you plan ahead you can save that
$oldtopic point so you can do something like this:

	git log pu ; # find $newtopic
	git checkout yourtopic
	git rebase --onto $newtopic base-yourtopic
	git tag -f base-yourtopic $newtopic

> I guess that brings up another question; I've been regularly rebasing
> the topics branches as master and next advances... probably more out
> of superstition than anything else.  Is that a bad idea for any reason?

It keeps the history shorter in gitk.  But otherwise it isn't bad.
Unless you are running into a lot of conflicts every time you rebase
and its wasting your time.  ;-)

I prefer to rebase the topics until they've merged to an integration
branch that doesn't rewind (e.g. master or next in git.git).
That way they have the shortest line possible in gitk between the
final merge and the start point.

There are good reasons why there's an "author" and a "committer"
field in commits.  Rebasing will change the committer field's
timestamp, but not the author field.  And author comes from the
email, to preserve the original date of development.
 
> Hmm... I guess some of this would be really good to get into the Howto
> section of the user guide when talking about git workflows!

Yea, I think so too.  We've adopted this model in git.git because
it works for our community.  A lot of other communities aren't
too far away, as we have a lot of crossover in members.  E.g. we
learned a lot from the kernel community.

-- 
Shawn.

^ permalink raw reply

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


On Oct 23, 2007, at 1:35 AM, 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.

True, and only the branches matching the remote currently pulled
should be considered. Tracking branches pointing to a different
remote need to be skipped.


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


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

Maybe Andreas' proposal could be extended as you describe.
But I don't think any merging should automatically be done. I'd
only support fast forwards. Merging always includes a risk
of unexpected changes to the code; even if there are no merge
conflicts detected by git. I think it is reasonable to leave
all such cases to the user for manual resolution. Supporting
fast-forward should be sufficient.

	Steffen

^ permalink raw reply

* Re: [PATCH] Add color to git-add--interactive diffs (Total different idea to solve the problem)
From: Peter Baumann @ 2007-10-23  5:34 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Tom Tobin, Dan Zwell, Jonathan del Strother, Shawn O. Pearce,
	Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0710230054130.25221@racer.site>

On Tue, Oct 23, 2007 at 12:55:44AM +0100, Johannes Schindelin wrote:
> Hi,
> 
> On Mon, 22 Oct 2007, Peter Baumann wrote:
> 
> > Wouldn't it make more sense to implement the diff coloring inside git 
> > apply so that you could use something like
> > 
> >         diff file1 file2|git apply --color
> > 
> > to make the generated diff with colors [1]? It already implements the
> > same semantic for generating a diffstat, using
> > 
> >         diff file1 file2|git apply --stat
> 
> No.  In both cases, "git diff" realises that the output is no terminal, 
> and switches off color generation.  (Just try with diff.color=true instead 
> of =auto.)
> 

I didn't mean git-diff here, instead I meant diff, so no coloring involved
on the diff side. The git-apply would be enhanced to do the coloring on
every diff it gets on its STDIN.

In the git-add -i case, the perl script whould do something along these
lines:

	foreach my $file (@files) {
		# read in the diff of a file *WITHOUT* using color
		@diff = `git-diff-files $file`;

		# ... store it away for later use in hunk selection ...


		# print out a nice colored diff for the user
		`echo @diff | git apply --color`
	}

Instead of handcoding the colorization in the git-add--interactive perl
script, just enhance git-apply to do the colorization *after the fact* for
you on _any_ patch you throw at it in its STDIN.

-Peter

^ permalink raw reply

* Re: What's cooking in git/spearce.git (topics)
From: Theodore Tso @ 2007-10-23  5:30 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Junio C Hamano, Johannes Schindelin, git
In-Reply-To: <20071023050726.GD14735@spearce.org>

On Tue, Oct 23, 2007 at 01:07:26AM -0400, Shawn O. Pearce wrote:
> Junio has in the past proposed rewinding next, especially after a
> significant release (e.g. 1.5.3).  

Hmm, yes.  I think I'd want to rewind next after a while; the thought
of next drifting hundreds or thousands of commits away from master
just gives me the heebee-jeebies.  I'm sure it mostly works, but it
just feels wrong.  :-)

> A bunch of folks (myself included if I recall correctly) didn't want
> to do this, as we create topic branches locally from things in next
> and sometimes make commits over them to improve the topic further.

I guess I don't see why this would be a hardship; would a quick rebase
on the topic branches more or less take care of the problem?  

I guess that brings up another question; I've been regularly rebasing
the topics branches as master and next advances... probably more out
of superstition than anything else.  Is that a bad idea for any reason?


Hmm... I guess some of this would be really good to get into the Howto
section of the user guide when talking about git workflows!

	       	    	       	       	     	 - Ted

^ permalink raw reply

* Re: What's cooking in git/spearce.git (topics)
From: Shawn O. Pearce @ 2007-10-23  5:07 UTC (permalink / raw)
  To: Theodore Tso; +Cc: Junio C Hamano, Johannes Schindelin, git
In-Reply-To: <20071023045632.GD27132@thunk.org>

Theodore Tso <tytso@mit.edu> wrote:
> On Tue, Oct 23, 2007 at 12:46:57AM -0400, Shawn O. Pearce wrote:
> > By merging only individual topics forked from master into next you
> > can merge those individual topics into master at different points
> > in time.  For example db/fetch-pack has been in next for many weeks
> > and hasn't yet merged into master, yet jc/am-quiet was forked after
> > db/fetch-pack started and has already merged into master.
> > 
> > Your way would make jc/am-quiet wait until db/fetch-pack was ready.
> > That's a big risk in the sense that your tree is "blocked" and even
> > simple changes are held up by ones that suddenly became a lot more
> > complex then you originally thought they were going to be.
> 
> Yes, true.  Alternatively, what I've been doing is that if I wasn't
> sure that a particular topic was ready to go to 'master' very shortly
> after it went into 'next', I would never let it go into 'next', but
> rather keep it in 'pu' (which is OK, because pu is constantly getting
> rewound).  But I guess the downside of that is you might get fewer
> testers for the code, because fewer people are probably tracking and
> testing 'pu' as compared to 'next'.
> 
> Right?

Yes, that's a good point.

I think in Git part of the reason less people track pu is because
its very volatile.  Not because of the rewind policy, but becuase
sometimes the code there doesn't work properly so using it for real
"production" work is pretty risky.  On the other hand most of the
code that merges into next has been reasonbly well reviewed and
tested, so following it for "production" work is not as risky.

Junio has in the past proposed rewinding next, especially after a
significant release (e.g. 1.5.3).  A bunch of folks (myself included
if I recall correctly) didn't want to do this, as we create topic
branches locally from things in next and sometimes make commits
over them to improve the topic further.  But I also make topic
branches for things in pu, so I might as well just shut up and
not complain.  :-)

Of course another thought that just came to mind is it is very easy
for me to review next with a

	git log -p --reverse origin/next..build-next

just before merging it into my build branch and compiling it locally.
If next rewound frequently (as pu does) this would be more difficult.

-- 
Shawn.

^ permalink raw reply

* Re: What's cooking in git/spearce.git (topics)
From: Theodore Tso @ 2007-10-23  4:56 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Junio C Hamano, Johannes Schindelin, git
In-Reply-To: <20071023044657.GC14735@spearce.org>

On Tue, Oct 23, 2007 at 12:46:57AM -0400, Shawn O. Pearce wrote:
> By merging only individual topics forked from master into next you
> can merge those individual topics into master at different points
> in time.  For example db/fetch-pack has been in next for many weeks
> and hasn't yet merged into master, yet jc/am-quiet was forked after
> db/fetch-pack started and has already merged into master.
> 
> Your way would make jc/am-quiet wait until db/fetch-pack was ready.
> That's a big risk in the sense that your tree is "blocked" and even
> simple changes are held up by ones that suddenly became a lot more
> complex then you originally thought they were going to be.

Yes, true.  Alternatively, what I've been doing is that if I wasn't
sure that a particular topic was ready to go to 'master' very shortly
after it went into 'next', I would never let it go into 'next', but
rather keep it in 'pu' (which is OK, because pu is constantly getting
rewound).  But I guess the downside of that is you might get fewer
testers for the code, because fewer people are probably tracking and
testing 'pu' as compared to 'next'.

Right?

					- Ted

^ permalink raw reply

* Re: What's cooking in git/spearce.git (topics)
From: Shawn O. Pearce @ 2007-10-23  4:46 UTC (permalink / raw)
  To: Theodore Tso; +Cc: Junio C Hamano, Johannes Schindelin, git
In-Reply-To: <20071023043321.GC27132@thunk.org>

Theodore Tso <tytso@mit.edu> wrote:
> On Tue, Oct 23, 2007 at 12:05:22AM -0400, Shawn O. Pearce wrote:
> >
> > Yes.  Because 'next' always has commits in it that never appear in
> > 'master'.  So any topic forked from master must merge into next.
> > It can't be a fast-forward.  No forced merging required.
> 
> Why is it the case that 'next' always commits that never appear in
> 'master'.  So far in how I've been doing things that hasn't been the
> case.  When I do a "git checkout master; git merge next", it's always
> been a fast-forward merge. 
> 
> Oh, I see.  That's because if you put some trivial changes in
> 'master', and then pull those changes into next, there will be merge
> commits in 'next' that will never be in 'master.  Is that it?  

Exactly.  This of course means that next has been growing in distance
from master for quite some time.  It has well over 1000 commits now
in git.git that aren't in master.  Most of those will never merge
there either.
 
> I had been trying to avoid that case by always putting new commits,
> even trivial ones, into 'next', and then having them drop into
> 'master' at the next cycle; so 'master' was always trailing 'next',
> but they were always the same commit string (i.e., 'master' was always
> a subset of 'next').  
> 
> Aside from the WC script not working right, are there other
> disadvantages to my doing things that way as opposed to the way the
> Junio has been running the git repository?

The reason Junio does what he does is flexibility.

By merging only individual topics forked from master into next you
can merge those individual topics into master at different points
in time.  For example db/fetch-pack has been in next for many weeks
and hasn't yet merged into master, yet jc/am-quiet was forked after
db/fetch-pack started and has already merged into master.

Your way would make jc/am-quiet wait until db/fetch-pack was ready.
That's a big risk in the sense that your tree is "blocked" and even
simple changes are held up by ones that suddenly became a lot more
complex then you originally thought they were going to be.

-- 
Shawn.

^ permalink raw reply

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

Jeff King <peff@peff.net> wrote:
> On Mon, Oct 22, 2007 at 09:19:58PM -0500, Dan Zwell wrote:
> 
> > This patch is againts Shawn Pearce's "pu" branch.
> 
> Don't do that. The code in 'pu' is a mess of half-working features. If
> your patch is accepted, then it has to be picked apart from those
> half-working features that aren't being accepted (which hopefully isn't
> hard if nobody has been working in the same area, but can be quite
> ugly).  Base your work on 'master' if possible, or 'next' if it relies
> on features only in next. If it relies on some topic branch that is
> _only_ in pu, then mention explicitly which topic.

And even when you base work on things in next, don't base it on the
tip of next.  Base it on a specific topic that is merged into next.
Next is also a mess of features, but they are more likely to be in
a working state than the features in pu.

Topics in next will merge to master at different times.  If your
changes depend on more than one topic that may make it more difficult
for the maintainer to merge your topic to master.

Fortunately In Dan's case the only topic in pu that impacted
git-add--interactive was his dz/color-addi topic, so this probably
applies to the tip of it just as well as it does to the tip of pu.

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH] execv_git_cmd(): also try PATH if everything else fails.
From: Shawn O. Pearce @ 2007-10-23  4:34 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Scott Parish, git
In-Reply-To: <Pine.LNX.4.64.0710221135100.25221@racer.site>

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> On Mon, 22 Oct 2007, Shawn O. Pearce wrote:
> > Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > > Earlier, we tried to find the git commands in several possible exec
> > > dirs.  Now, if all of these failed, try to find the git command in
> > > PATH.
> > ...
> > > diff --git a/exec_cmd.c b/exec_cmd.c
> > > index 9b74ed2..70b84b0 100644
> > > --- a/exec_cmd.c
> > > +++ b/exec_cmd.c
> > > @@ -36,7 +36,8 @@ int execv_git_cmd(const char **argv)
> > >  	int i;
> > >  	const char *paths[] = { current_exec_path,
> > >  				getenv(EXEC_PATH_ENVIRONMENT),
> > > -				builtin_exec_path };
> > > +				builtin_exec_path,
> > > +				"" };
> > 
> > So if the user sets GIT_EXEC_PATH="" and exports it we'll search $PATH 
> > before the builtin exec path that Git was compiled with? Are we sure we 
> > want to do that?
> 
> I thought the proper way to unset EXEC_PATH was to "unset GIT_EXEC_PATH".  
> In that case, getenv(EXEC_PATH_ENVIRONMENT) returns NULL and we're fine, 
> no?

Sure.  But can't you also export an environment variable that is
set to the empty string?  At least on UNIX.  Windows thinks unset
and empty string are the same thing.

-- 
Shawn.

^ permalink raw reply

* Re: What's cooking in git/spearce.git (topics)
From: Theodore Tso @ 2007-10-23  4:33 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Junio C Hamano, Johannes Schindelin, git
In-Reply-To: <20071023040522.GX14735@spearce.org>

On Tue, Oct 23, 2007 at 12:05:22AM -0400, Shawn O. Pearce wrote:
>
> Yes.  Because 'next' always has commits in it that never appear in
> 'master'.  So any topic forked from master must merge into next.
> It can't be a fast-forward.  No forced merging required.

Why is it the case that 'next' always commits that never appear in
'master'.  So far in how I've been doing things that hasn't been the
case.  When I do a "git checkout master; git merge next", it's always
been a fast-forward merge. 

Oh, I see.  That's because if you put some trivial changes in
'master', and then pull those changes into next, there will be merge
commits in 'next' that will never be in 'master.  Is that it?  

I had been trying to avoid that case by always putting new commits,
even trivial ones, into 'next', and then having them drop into
'master' at the next cycle; so 'master' was always trailing 'next',
but they were always the same commit string (i.e., 'master' was always
a subset of 'next').  

Aside from the WC script not working right, are there other
disadvantages to my doing things that way as opposed to the way the
Junio has been running the git repository?

						- Ted

^ permalink raw reply

* Re: git.el fails on non-git managed files
From: Shawn O. Pearce @ 2007-10-23  4:31 UTC (permalink / raw)
  To: racin; +Cc: git
In-Reply-To: <1193077008.471ce910f15c5@imp.free.fr>

racin@free.fr wrote:
> I found the following on the development version of git.el: saving
> non-git-managed files in Emacs threw an error.
> 
> It is due to a simple error in the call to condition-case in a
> recently added function, git-update-save-file.
> 
> I attached the patch for your convenience.

I'm not sure what happened, but I didn't receive a patch with
your email.  Would you mind resending it to the list?  You may
also want to file a bug with your distribution to get the Emacs
bindings included.
 
-- 
Shawn.

^ permalink raw reply

* Re: [PATCH] don't set-group-id on directories on apple
From: Scott Parish @ 2007-10-23  4:30 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <20071022142945.GO16291@srparish.net>

On Mon, Oct 22, 2007 at 07:29:45AM -0700, Scott Parish wrote:

> On Mon, Oct 22, 2007 at 03:16:01PM +0100, Johannes Schindelin wrote:
> 
> > On Mon, 22 Oct 2007, Scott R Parish wrote:
> > 
> > > "git init --shared=all" was failing because chmod was returning EPERM.
> > 
> > Not here. 
> > 
> > Is it possible that you have stricter permission settings?

I finally figured it out. I keep my home directory encrypted, but
its pretty slow (especially compiles) and i don't care who steals
open source code i'm playing with, so i keep that in /Users/Shared.
Since mkdir() on darwin keeps the parents group by default, the
group on my git clone was wheel, which i'm not a member of.

sRp

-- 
Scott Parish
http://srparish.net/

^ permalink raw reply

* Re: [PATCH] Let git-add--interactive read "git colors" from git-config
From: Jeff King @ 2007-10-23  4:29 UTC (permalink / raw)
  To: Dan Zwell
  Cc: Shawn O. Pearce, Wincent Colaiuta, Git Mailing List,
	Jonathan del Strother, Johannes Schindelin, Frank Lichtenheld
In-Reply-To: <20071022211958.045895ac@danzwell.com>

On Mon, Oct 22, 2007 at 09:19:58PM -0500, Dan Zwell wrote:

> This patch is againts Shawn Pearce's "pu" branch.

Don't do that. The code in 'pu' is a mess of half-working features. If
your patch is accepted, then it has to be picked apart from those
half-working features that aren't being accepted (which hopefully isn't
hard if nobody has been working in the same area, but can be quite
ugly).  Base your work on 'master' if possible, or 'next' if it relies
on features only in next. If it relies on some topic branch that is
_only_ in pu, then mention explicitly which topic.

-Peff

^ 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