[PATCH] hash-object: cleanup handling of command line options
git hash-object used to process the --stdin command line argument before reading subsequent arguments. This caused 'git hash-object --stdin -w' to fail to actually write the object into the database, while '-w --stdin' properly did. Now git hash-object first reads all arguments, and then processes them.
This regresses one insane use case. git hash-object used to allow multiple --stdin arguments on the command line:
$ git hash-object --stdin --stdin
foo
^D
bar
^DNow git hash-object errors out if --stdin is given more than once.
Reported by Josh Triplett through
http://bugs.debian.org/464432
Signed-off-by: Gerrit Pape <pape@smarden.org>
---
On Fri, Feb 15, 2008 at 09:31:10AM -0800, Junio C Hamano wrote:
> Having said all that, I think "--stdin file2 <file1" behaviour
> can be kept without regressing by a patch like this on top of
> your fix, and we can drop the first "regression warning" in the
> commit log message if we did so.
Yes, this seems the better choice. I adapted the commit message a bit, and swapped file0 and file1 in the test description and the selftest where appropriate, it's been mixed up.
Regards, Gerrit.
hash-object.c | 12 +++++++++++-
t/t5303-hash-object.sh | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 1 deletions(-)
create mode 100755 t/t5303-hash-object.sh
Show changes to 2 files +46 −1
hash-object.c, t/t5303-hash-object.sh
diff --git a/hash-object.c b/hash-object.c
index 0a58f3f..61e7160 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -41,6 +41,7 @@ int main(int argc, char **argv)
const char *prefix = NULL;
int prefix_length = -1;
int no_more_flags = 0;
+ int hashstdin = 0;
git_config(git_default_config);
@@ -65,13 +66,20 @@ int main(int argc, char **argv)
else if (!strcmp(argv[i], "--help"))
usage(hash_object_usage);
else if (!strcmp(argv[i], "--stdin")) {
- hash_stdin(type, write_object);
+ if (hashstdin)
+ die("Multiple --stdin arguments are not supported");
+ hashstdin = 1;
}
else
usage(hash_object_usage);
}
else {
const char *arg = argv[i];
+
+ if (hashstdin) {
+ hash_stdin(type, write_object);
+ hashstdin = 0;
+ }
if (0 <= prefix_length)
arg = prefix_filename(prefix, prefix_length,
arg);
@@ -79,5 +87,7 @@ int main(int argc, char **argv)
no_more_flags = 1;
}
}
+ if (hashstdin)
+ hash_stdin(type, write_object);
return 0;
}
diff --git a/t/t5303-hash-object.sh b/t/t5303-hash-object.sh
new file mode 100755
index 0000000..543c078
--- /dev/null
+++ b/t/t5303-hash-object.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+test_description=git-hash-object
+
+. ./test-lib.sh
+
+test_expect_success \
+ 'git hash-object -w --stdin saves the object' \
+ 'obname=$(echo foo | git hash-object -w --stdin) &&
+ obpath=$(echo $obname | sed -e "s/\(..\)/\1\//") &&
+ test -r .git/objects/"$obpath" &&
+ rm -f .git/objects/"$obpath"'
+
+test_expect_success \
+ 'git hash-object --stdin -w saves the object' \
+ 'obname=$(echo foo | git hash-object --stdin -w) &&
+ obpath=$(echo $obname | sed -e "s/\(..\)/\1\//") &&
+ test -r .git/objects/"$obpath" &&
+ rm -f .git/objects/"$obpath"'
+
+test_expect_success \
+ 'git hash-object --stdin file1 <file0 first operates on file0, then file1' \
+ 'echo foo > file1 &&
+ obname0=$(echo bar | git hash-object --stdin) &&
+ obname1=$(git hash-object file1) &&
+ obname0new=$(echo bar | git hash-object --stdin file1 | sed -n -e 1p) &&
+ obname1new=$(echo bar | git hash-object --stdin file1 | sed -n -e 2p) &&
+ test "$obname0" = "$obname0new" &&
+ test "$obname1" = "$obname1new"'
+
+test_expect_success \
+ 'git hash-object refuses multiple --stdin arguments' \
+ '! git hash-object --stdin --stdin < file1'
+
+test_done
--
1.5.4.2