From 60da8b15c1b77706e0701cccef2d534a1c3825ad Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 20 Nov 2009 02:50:21 -0800 Subject: [PATCH] Make --stdin option to "log" family read also pathspecs Similar to the command line arguments, after giving zero or more revs, you can feed a line "--" and then feed pathspecs one at a time. With this ( echo ^maint echo -- echo Documentation ) | git log --stat --oneline --stdin master -- t lists commits that touch Documentation/ or t/ between maint and master. Signed-off-by: Junio C Hamano --- Documentation/rev-list-options.txt | 4 +- revision.c | 72 ++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 88ad40511..b44fdd9f0 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -246,7 +246,9 @@ endif::git-rev-list[] --stdin:: In addition to the '' listed on the command - line, read them from the standard input. + line, read them from the standard input. If a '--' separator is + seen, stop reading commits and start reading paths to limit the + result. ifdef::git-rev-list[] --quiet:: diff --git a/revision.c b/revision.c index 4410a45a0..8750c20e0 100644 --- a/revision.c +++ b/revision.c @@ -953,9 +953,38 @@ int handle_revision_arg(const char *arg, struct rev_info *revs, return 0; } -static void read_revisions_from_stdin(struct rev_info *revs) +static void read_pathspec_from_stdin(struct rev_info *revs, struct strbuf *sb, const char ***prune_data) +{ + const char **prune = *prune_data; + int prune_nr; + int prune_alloc; + + /* count existing ones */ + if (!prune) + prune_nr = 0; + else + for (prune_nr = 0; prune[prune_nr]; prune_nr++) + ; + prune_alloc = prune_nr; /* not really, but we do not know */ + + while (strbuf_getwholeline(sb, stdin, '\n') != EOF) { + int len = sb->len; + if (len && sb->buf[len - 1] == '\n') + sb->buf[--len] = '\0'; + ALLOC_GROW(prune, prune_nr+1, prune_alloc); + prune[prune_nr++] = xstrdup(sb->buf); + } + if (prune) { + ALLOC_GROW(prune, prune_nr+1, prune_alloc); + prune[prune_nr] = NULL; + } + *prune_data = prune; +} + +static void read_revisions_from_stdin(struct rev_info *revs, const char ***prune) { struct strbuf sb; + int seen_dashdash = 0; strbuf_init(&sb, 1000); while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) { @@ -964,11 +993,18 @@ static void read_revisions_from_stdin(struct rev_info *revs) sb.buf[--len] = '\0'; if (!len) break; - if (sb.buf[0] == '-') + if (sb.buf[0] == '-') { + if (len == 2 && sb.buf[1] == '-') { + seen_dashdash = 1; + break; + } die("options not supported in --stdin mode"); + } if (handle_revision_arg(sb.buf, revs, 0, 1)) die("bad revision '%s'", sb.buf); } + if (seen_dashdash) + read_pathspec_from_stdin(revs, &sb, prune); strbuf_release(&sb); } @@ -1220,6 +1256,34 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx, ctx->argc -= n; } +static void append_prune_data(const char ***prune_data, const char **av) +{ + const char **prune = *prune_data; + int prune_nr; + int prune_alloc; + + if (!prune) { + *prune_data = av; + return; + } + + /* count existing ones */ + for (prune_nr = 0; prune[prune_nr]; prune_nr++) + ; + prune_alloc = prune_nr; /* not really, but we do not know */ + + while (*av) { + ALLOC_GROW(prune, prune_nr+1, prune_alloc); + prune[prune_nr++] = *av; + av++; + } + if (prune) { + ALLOC_GROW(prune, prune_nr+1, prune_alloc); + prune[prune_nr] = NULL; + } + *prune_data = prune; +} + /* * Parse revision information, filling in the "rev_info" structure, * and removing the used arguments from the argument list. @@ -1294,7 +1358,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch } if (read_from_stdin++) die("--stdin given twice?"); - read_revisions_from_stdin(revs); + read_revisions_from_stdin(revs, &prune_data); continue; } @@ -1322,7 +1386,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch for (j = i; j < argc; j++) verify_filename(revs->prefix, argv[j]); - prune_data = argv + i; + append_prune_data(&prune_data, argv + i); break; } } -- 2.30.2