Junio C Hamano <gitster@xxxxxxxxx> writes: > Junio C Hamano <gitster@xxxxxxxxx> writes: > >> Junio C Hamano <gitster@xxxxxxxxx> writes: >> >>> Jeff King <peff@xxxxxxxx> writes: >>> >>>> but that code path should be fixed properly (with a use_stdin flag in >>>> the filespec). >>> >>> Yes, just as I said; I am finding more and more issues with the >>> no-index hack that I have been fixing a bit by bit since I send the >>> message you responded to. >> >> It is not ready yet, but here are a few patches WIP. > > And this is the second clean-up And this is the third one. -- >8 -- Subject: [PATCH 3/?] diff-index.c: "git diff" has no need to read blob from the standard input Only "diff --no-index -" does. Bolting the logic into the low-level function diff_populate_filespec() was a layering violation from day one. Move populate_from_stdin() function out of the generic diff.c to its only user, diff-index.c. Also make sure "-" from the command line stays a special token "read from the standard input", even if we later decide to sanitize the result from prefix_filename() function in a few obvious ways, e.g. removing unnecessary "./" prefix, duplicated slashes "//" in the middle, etc. Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- diff-no-index.c | 33 +++++++++++++++++++++++++++++++-- diff.c | 21 +-------------------- diffcore.h | 1 + 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/diff-no-index.c b/diff-no-index.c index a5c1e3e..9385d53 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -32,6 +32,12 @@ static int read_directory(const char *path, struct string_list *list) return 0; } +/* + * This should be "(standard input)", but it will probably expose many + * more breakages. + */ +static const char file_from_standard_input[] = "-"; + static int get_mode(const char *path, int *mode) { struct stat st; @@ -42,7 +48,7 @@ static int get_mode(const char *path, int *mode) else if (!strcasecmp(path, "nul")) *mode = 0; #endif - else if (!strcmp(path, "-")) + else if (path == file_from_standard_input) *mode = create_ce_mode(0666); else if (lstat(path, &st)) return error("Could not access '%s'", path); @@ -51,6 +57,23 @@ static int get_mode(const char *path, int *mode) return 0; } +static int populate_from_stdin(struct diff_filespec *s) +{ + struct strbuf buf = STRBUF_INIT; + size_t size = 0; + + if (strbuf_read(&buf, 0, 0) < 0) + return error("error while reading from stdin %s", + strerror(errno)); + + s->should_munmap = 0; + s->data = strbuf_detach(&buf, &size); + s->size = size; + s->should_free = 1; + s->nongit_stdin = 1; + return 0; +} + static int queue_diff(struct diff_options *o, const char *name1, const char *name2) { @@ -143,8 +166,14 @@ static int queue_diff(struct diff_options *o, name2 = "/dev/null"; d1 = alloc_filespec(name1); d2 = alloc_filespec(name2); + fill_filespec(d1, null_sha1, mode1); + if (name1 == file_from_standard_input) + populate_from_stdin(d1); + fill_filespec(d2, null_sha1, mode2); + if (name2 == file_from_standard_input) + populate_from_stdin(d2); diff_queue(&diff_queued_diff, d1, d2); return 0; @@ -240,7 +269,7 @@ void diff_no_index(struct rev_info *revs, * stdin should be spelled as "-"; if you have * path that is "-", spell it as "./-". */ - p = p; + p = file_from_standard_input; else if (prefixlen) p = xstrdup(prefix_filename(prefix, prefixlen, p)); paths[i] = p; diff --git a/diff.c b/diff.c index 1a594df..0c73c84 100644 --- a/diff.c +++ b/diff.c @@ -2619,22 +2619,6 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int return 0; } -static int populate_from_stdin(struct diff_filespec *s) -{ - struct strbuf buf = STRBUF_INIT; - size_t size = 0; - - if (strbuf_read(&buf, 0, 0) < 0) - return error("error while reading from stdin %s", - strerror(errno)); - - s->should_munmap = 0; - s->data = strbuf_detach(&buf, &size); - s->size = size; - s->should_free = 1; - return 0; -} - static int diff_populate_gitlink(struct diff_filespec *s, int size_only) { int len; @@ -2684,9 +2668,6 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) struct stat st; int fd; - if (!strcmp(s->path, "-")) - return populate_from_stdin(s); - if (lstat(s->path, &st) < 0) { if (errno == ENOENT) { err_empty: @@ -3048,7 +3029,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one) if (DIFF_FILE_VALID(one)) { if (!one->sha1_valid) { struct stat st; - if (!strcmp(one->path, "-")) { + if (one->nongit_stdin) { hashcpy(one->sha1, null_sha1); return; } diff --git a/diffcore.h b/diffcore.h index 8f32b82..ef4fe17 100644 --- a/diffcore.h +++ b/diffcore.h @@ -42,6 +42,7 @@ struct diff_filespec { #define DIFF_FILE_VALID(spec) (((spec)->mode) != 0) unsigned should_free : 1; /* data should be free()'ed */ unsigned should_munmap : 1; /* data should be munmap()'ed */ + unsigned nongit_stdin : 1; /* data is from a nongit source */ unsigned dirty_submodule : 2; /* For submodules: its work tree is dirty */ #define DIRTY_SUBMODULE_UNTRACKED 1 #define DIRTY_SUBMODULE_MODIFIED 2 -- 1.7.11.1.184.g3ee8f69 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html