@@ -10,7 +10,7 @@ SYNOPSIS
--------
[verse]
'git diff-blob' <blob> <blob>
-'git diff-blob' --stdin
+'git diff-blob' --stdin [-z]
DESCRIPTION
-----------
@@ -26,6 +26,10 @@ OPTIONS
from the command line. Instead, it reads lines containing two <blob>
from its standard input. (Use a single space as separator.)
+-z::
+ When `--stdin` has been given, use NUL characters to separate blob
+ inputs and diff outputs.
+
include::pretty-formats.txt[]
include::diff-format.txt[]
@@ -81,23 +81,39 @@ static void parse_blob_stdin(struct object_array *blob_pair,
object_context_release(&oc);
}
-static void diff_blob_stdin(struct repository *repo, struct diff_options *opts)
+static void diff_blob_stdin(struct repository *repo, struct diff_options *opts,
+ int null_term)
{
struct strbuf sb = STRBUF_INIT;
struct string_list_item *item;
- while (strbuf_getline(&sb, stdin) != EOF) {
+ while (1) {
struct object_array blob_pair = OBJECT_ARRAY_INIT;
struct string_list list = STRING_LIST_INIT_NODUP;
- if (string_list_split_in_place(&list, sb.buf, " ", -1) != 2)
- die("two blobs not provided");
+ if (null_term) {
+ if (strbuf_getline_nul(&sb, stdin) == EOF)
+ break;
+ parse_blob_stdin(&blob_pair, repo, sb.buf);
- for_each_string_list_item(item, &list) {
- parse_blob_stdin(&blob_pair, repo, item->string);
+ if (strbuf_getline_nul(&sb, stdin) == EOF)
+ break;
+ parse_blob_stdin(&blob_pair, repo, sb.buf);
+ } else {
+ if (strbuf_getline(&sb, stdin) == EOF)
+ break;
+
+ if (string_list_split_in_place(&list, sb.buf, " ", -1) != 2)
+ die("two blobs not provided");
+
+ for_each_string_list_item(item, &list) {
+ parse_blob_stdin(&blob_pair, repo, item->string);
+ }
}
diff_blobs(&blob_pair.objects[0], &blob_pair.objects[1], opts);
+ if (null_term)
+ printf("%c", '\0');
string_list_clear(&list, 1);
object_array_clear(&blob_pair);
@@ -112,16 +128,19 @@ int cmd_diff_blob(int argc, const char **argv, const char *prefix,
struct object_array_entry *old_blob, *new_blob;
struct rev_info revs;
int read_stdin = 0;
+ int null_term = 0;
int ret;
const char * const usage[] = {
N_("git diff-blob <blob> <blob>"),
- N_("git diff-blob --stdin"),
+ N_("git diff-blob --stdin [-z]"),
NULL
};
struct option options[] = {
OPT_BOOL(0, "stdin", &read_stdin,
N_("read blob pairs from stdin")),
+ OPT_BOOL('z', NULL, &null_term,
+ N_("inputed blobs and outputted diffs terminated with NUL")),
OPT_END()
};
@@ -149,13 +168,13 @@ int cmd_diff_blob(int argc, const char **argv, const char *prefix,
usage_with_options(usage, options);
revs.diffopt.no_free = 1;
- diff_blob_stdin(repo, &revs.diffopt);
+ diff_blob_stdin(repo, &revs.diffopt, null_term);
revs.diffopt.no_free = 0;
diff_free(&revs.diffopt);
break;
case 2:
- if (read_stdin)
+ if (read_stdin || null_term)
usage_with_options(usage, options);
old_blob = &revs.pending.objects[0];
The "--stdin" option for git-diff-blob(1) reads two space separated blobs for each line of input. A blob may be specified by its ID or a path-scoped revision that resolves to a blob. It is possible for the path to contain whitespace or newline characters which must be escaped. To make input more simple, teach git-diff-blob(1) the "-z" option which changes the input delimiter for each blob to a NUL character. With this option, the command waits two NUL terminated blobs to read and then generates the diff. The diff output is also NUL terminated to help differentiate between outputted diffs. Signed-off-by: Justin Tobler <jltobler@gmail.com> --- Documentation/git-diff-blob.txt | 6 +++++- builtin/diff-blob.c | 37 +++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 10 deletions(-)