[PATCH 3/3] builtin/diff-blob: Add "-z" option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 Documentation/git-diff-blob.txt |  6 +++++-
 builtin/diff-blob.c             | 37 +++++++++++++++++++++++++--------
 2 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/Documentation/git-diff-blob.txt b/Documentation/git-diff-blob.txt
index f6ecd522fa..36cd686bb1 100644
--- a/Documentation/git-diff-blob.txt
+++ b/Documentation/git-diff-blob.txt
@@ -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[]
diff --git a/builtin/diff-blob.c b/builtin/diff-blob.c
index 45edfdd979..60c92cec9c 100644
--- a/builtin/diff-blob.c
+++ b/builtin/diff-blob.c
@@ -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];
-- 
2.47.1





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux