[PATCH] diff-cache/tree compatible output for show-diff (take 2).
From: Junio C Hamano <hidden>
Date: 2016-06-15 22:41:54
This patch changes the output format of the show-diff command to
match that of the diff-cache/tree commands. One type of record
it can produce that diff-cache/tree do not is of this form:
U path <record-terminator>
This is emitted once per unmerged path, no matter how many
unmerged stages there are. The diff-tree-helper program is also
taught about this and warns about such input records.
The -z flag has the same meaning as diff-cache/tree commands;
the output records are terminated with a NUL instead of a '\n'.
Just like diff-cache takes a meaningless -r flag, it also
ignores a -r.
The previous default behaviour of getting patch output can be
obtained by specifying a -p flag.
Signed-off-by: Junio C Hamano <redacted>
---
diff-tree-helper.c | 27 ++++++++++++++++---------
show-diff.c | 57 +++++++++++++++++++++++++++++++++++++----------------
2 files changed, 58 insertions(+), 26 deletions(-)
--- k/diff-tree-helper.c
+++ l/diff-tree-helper.c@@ -44,6 +44,9 @@ static int parse_oneside_change(const ch return 0; } +#define PLEASE_WARN -1 +#define WARNED_OURSELVES -2 + static int parse_diff_tree_output(const char *buf, struct diff_spec *old, struct diff_spec *new,
@@ -52,6 +55,9 @@ static int parse_diff_tree_output(const int ch; switch (*cp++) { + case 'U': + fprintf(stderr, "warning: unmerged path %s\n", cp+1); + return WARNED_OURSELVES; case '+': old->file_valid = 0; return parse_oneside_change(cp, new, path);
@@ -61,7 +67,7 @@ static int parse_diff_tree_output(const case '*': break; default: - return -1; + return PLEASE_WARN; } /* This is for '*' entries */
@@ -74,26 +80,26 @@ static int parse_diff_tree_output(const cp++; } if (strncmp(cp, "->", 2)) - return -1; + return PLEASE_WARN; cp += 2; while ((ch = *cp) && ('0' <= ch && ch <= '7')) { new->mode = (new->mode << 3) | (ch - '0'); cp++; } if (strncmp(cp, "\tblob\t", 6)) - return -1; + return PLEASE_WARN; cp += 6; if (get_sha1_hex(cp, old->u.sha1)) - return -1; + return PLEASE_WARN; cp += 40; if (strncmp(cp, "->", 2)) - return -1; + return PLEASE_WARN; cp += 2; if (get_sha1_hex(cp, new->u.sha1)) - return -1; + return PLEASE_WARN; cp += 40; if (*cp++ != '\t') - return -1; + return PLEASE_WARN; strcpy(path, cp); return 0; }
@@ -120,13 +126,16 @@ int main(int ac, char **av) { /* the remaining parameters are paths patterns */ while (1) { + int status; struct diff_spec old, new; char path[PATH_MAX]; read_line(&sb, stdin, line_termination); if (sb.eof) break; - if (parse_diff_tree_output(sb.buf, &old, &new, path)) { - fprintf(stderr, "cannot parse %s\n", sb.buf); + status = parse_diff_tree_output(sb.buf, &old, &new, path); + if (status) { + if (status == PLEASE_WARN) + fprintf(stderr, "cannot parse %s\n", sb.buf); continue; } if (1 < ac && !matches_pathspec(path, av+1, ac-1)) --- k/show-diff.c +++ l/show-diff.c
@@ -6,7 +6,8 @@ #include "cache.h" #include "diff.h" -static const char *show_diff_usage = "show-diff [-q] [-s] [-z] [paths...]"; +static const char *show_diff_usage = +"show-diff [-q] [-s] [-r] [-z] [-p] [paths...]"; static int matches_pathspec(struct cache_entry *ce, char **spec, int cnt) {
@@ -23,24 +24,40 @@ static int matches_pathspec(struct cache return 0; } +static void show_file(int pfx, struct cache_entry *ce, int line_termination) +{ + printf("%c%o\t%s\t%s\t%s%c", pfx, ntohl(ce->ce_mode), "blob", + sha1_to_hex(ce->sha1), ce->name, line_termination); +} + int main(int argc, char **argv) { int silent = 0; int silent_on_nonexisting_files = 0; - int machine_readable = 0; + int patch = 0; + int line_termination = '\n'; int reverse = 0; int entries = read_cache(); int i; while (1 < argc && argv[1][0] == '-') { if (!strcmp(argv[1], "-R")) - reverse = 1; + patch = reverse = 1; /* works only for patch */ else if (!strcmp(argv[1], "-s")) - silent_on_nonexisting_files = silent = 1; + patch = silent_on_nonexisting_files = silent = 1; else if (!strcmp(argv[1], "-q")) - silent_on_nonexisting_files = 1; + patch = silent_on_nonexisting_files = 1; + else if (!strcmp(argv[1], "-p")) { + patch = 1; + line_termination = '\n'; + } + else if (!strcmp(argv[1], "-r")) + ; /* diff-cache and diff-tree compatible + * is the default now. + */ else if (!strcmp(argv[1], "-z")) - machine_readable = 1; + /* makes sense only non-patch */ + patch = line_termination = 0; else usage(show_diff_usage); argv++; argc--;
@@ -64,11 +81,10 @@ int main(int argc, char **argv) continue; if (ce_stage(ce)) { - if (machine_readable) - printf("U %s%c", ce->name, 0); + if (patch) + printf("%s: unmerged\n", ce->name); else - printf("%s: Unmerged\n", - ce->name); + printf("U %s%c", ce->name, line_termination); while (i < entries && !strcmp(ce->name, active_cache[i]->name)) i++;
@@ -77,26 +93,33 @@ int main(int argc, char **argv) } if (stat(ce->name, &st) < 0) { + /* deleted */ if (errno == ENOENT && silent_on_nonexisting_files) continue; - if (machine_readable) - printf("X %s%c", ce->name, 0); - else { + if (patch) { printf("%s: %s\n", ce->name, strerror(errno)); if (errno == ENOENT) show_diff_empty(ce, reverse); } + else + show_file('-', ce, line_termination); continue; } changed = cache_match_stat(ce, &st); if (!changed) continue; - if (!machine_readable) - printf("%s: %s\n", ce->name, sha1_to_hex(ce->sha1)); - else { - printf("%s %s%c", sha1_to_hex(ce->sha1), ce->name, 0); + if (!patch) { + static char *no_sha1_hex = + "0000000000000000000000000000000000000000"; + printf("*%o->%o\t%s\t%s->%s\t%s%c", + ntohl(ce->ce_mode), st.st_mode, + "blob", sha1_to_hex(ce->sha1), no_sha1_hex, + ce->name, line_termination); continue; } + else + printf("%s %s%c", sha1_to_hex(ce->sha1), ce->name, + line_termination); if (silent) continue;