Code

git-hash-object: Add --stdin-paths option
authorAdam Roben <aroben@apple.com>
Fri, 23 May 2008 14:19:38 +0000 (16:19 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 23 May 2008 19:06:35 +0000 (12:06 -0700)
This allows multiple paths to be specified on stdin.

Signed-off-by: Adam Roben <aroben@apple.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-hash-object.txt
hash-object.c
t/t1007-hash-object.sh

index 33030c022f1b86a8dba281ff04537c1a40cb6782..99a21434b53a40a1b317e9d3da1728ca22d76b53 100644 (file)
@@ -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>
index 61e7160b361f60e6d673ab64aa3d22c1a783d057..0a7ac2fe2adf820a171898b9e51b245c063018cc 100644 (file)
@@ -6,6 +6,7 @@
  */
 #include "cache.h"
 #include "blob.h"
+#include "quote.h"
 
 static void hash_object(const char *path, enum object_type type, int write_object)
 {
@@ -20,6 +21,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)
@@ -30,8 +32,27 @@ static void hash_stdin(const char *type, int write_object)
        printf("%s\n", sha1_to_hex(sha1));
 }
 
+static void hash_stdin_paths(const char *type, int write_objects)
+{
+       struct strbuf buf, nbuf;
+
+       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_objects);
+       }
+       strbuf_release(&buf);
+       strbuf_release(&nbuf);
+}
+
 static const char hash_object_usage[] =
-"git-hash-object [-t <type>] [-w] [--stdin] <file>...";
+"git-hash-object [ [-t <type>] [-w] [--stdin] <file>... | --stdin-paths < <list-of-paths> ]";
 
 int main(int argc, char **argv)
 {
@@ -42,6 +63,7 @@ int main(int argc, char **argv)
        int prefix_length = -1;
        int no_more_flags = 0;
        int hashstdin = 0;
+       int stdin_paths = 0;
 
        git_config(git_default_config);
 
@@ -65,7 +87,19 @@ int main(int argc, char **argv)
                        }
                        else if (!strcmp(argv[i], "--help"))
                                usage(hash_object_usage);
+                       else if (!strcmp(argv[i], "--stdin-paths")) {
+                               if (hashstdin) {
+                                       error("Can't use --stdin-paths with --stdin");
+                                       usage(hash_object_usage);
+                               }
+                               stdin_paths = 1;
+
+                       }
                        else if (!strcmp(argv[i], "--stdin")) {
+                               if (stdin_paths) {
+                                       error("Can't use %s with --stdin-paths", argv[i]);
+                                       usage(hash_object_usage);
+                               }
                                if (hashstdin)
                                        die("Multiple --stdin arguments are not supported");
                                hashstdin = 1;
@@ -76,6 +110,11 @@ int main(int argc, char **argv)
                else {
                        const char *arg = argv[i];
 
+                       if (stdin_paths) {
+                               error("Can't specify files (such as \"%s\") with --stdin-paths", arg);
+                               usage(hash_object_usage);
+                       }
+
                        if (hashstdin) {
                                hash_stdin(type, write_object);
                                hashstdin = 0;
@@ -87,6 +126,10 @@ int main(int argc, char **argv)
                        no_more_flags = 1;
                }
        }
+
+       if (stdin_paths)
+               hash_stdin_paths(type, write_object);
+
        if (hashstdin)
                hash_stdin(type, write_object);
        return 0;
index 2019ea789107dc166c24648ff53a4e954aece386..05262954abbd5aa054fbde44f946d58e07a54574 100755 (executable)
@@ -52,6 +52,15 @@ test_expect_success "multiple '--stdin's are rejected" '
        test_must_fail git hash-object --stdin --stdin < example
 '
 
+test_expect_success "Can't use --stdin and --stdin-paths together" '
+       test_must_fail git hash-object --stdin --stdin-paths &&
+       test_must_fail git hash-object --stdin-paths --stdin
+'
+
+test_expect_success "Can't pass filenames as arguments with --stdin-paths" '
+       test_must_fail git hash-object --stdin-paths hello < example
+'
+
 # Behavior
 
 push_repo
@@ -98,4 +107,27 @@ for args in "-w --stdin" "--stdin -w"; do
        pop_repo
 done
 
+filenames="hello
+example"
+
+sha1s="$hello_sha1
+$example_sha1"
+
+test_expect_success "hash two files with names on stdin" '
+       test "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object --stdin-paths)"
+'
+
+for args in "-w --stdin-paths" "--stdin-paths -w"; do
+       push_repo
+
+       test_expect_success "hash two files with names on stdin and write to database ($args)" '
+               test "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object $args)"
+       '
+
+       test_blob_exists $hello_sha1
+       test_blob_exists $example_sha1
+
+       pop_repo
+done
+
 test_done