* Re: Q: supplying large sets of path to git commands
2009-10-16 10:40 Q: supplying large sets of path to git commands Constantine Plotnikov
@ 2009-10-16 22:08 ` Junio C Hamano
0 siblings, 0 replies; 2+ messages in thread
From: Junio C Hamano @ 2009-10-16 22:08 UTC (permalink / raw)
To: Constantine Plotnikov; +Cc: Git Mailing List
Constantine Plotnikov <constantine.plotnikov@gmail.com> writes:
> Some git commands like git check-attr supports receiving paths from
> stdin.
Here is how one might implement it for diff/log family of commands that
use "setup_revisions()".
I didn't test it (of course) beyond running
./git diff --name-only HEAD | ./git diff --stdin-paths --stat -p
in order to include the patch text in this message, and running
./git diff --name-only | ./git log --stdin-paths --no-merges --stat
---
Documentation/git-rev-list.txt | 1 +
Documentation/rev-list-options.txt | 7 ++++
revision.c | 59 +++++++++++++++++++++++++++++++++--
3 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index 3341d1b..8fa276c 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -46,6 +46,7 @@ SYNOPSIS
[ \--reverse ]
[ \--walk-reflogs ]
[ \--no-walk ] [ \--do-walk ]
+ [ \--stdin-paths | \--stdin-paths-z ]
<commit>... [ \-- <paths>... ]
DESCRIPTION
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index bf66116..9960de8 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -317,6 +317,13 @@ The following options select the commits to be shown:
Commits modifying the given <paths> are selected.
+--stdin-paths::
+--stdin-paths-z::
+
+ Additionally read <paths> (see above) from the standard input,
+ one path per line terminated with linefeed (or NUL when
+ --stdin-paths-z is used).
+
--simplify-by-decoration::
Commits that are referred by some branch or tag are selected.
diff --git a/revision.c b/revision.c
index 9fc4e8d..4caccdb 100644
--- a/revision.c
+++ b/revision.c
@@ -1218,6 +1218,38 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,
ctx->argc -= n;
}
+enum append_stdin_mode {
+ APPEND_STDIN = 1,
+ APPEND_STDIN_Z = 2,
+};
+
+static const char **grab_pathspec(const char *prefix, const char **argv,
+ enum append_stdin_mode append_stdin)
+{
+ const char **nargv;
+ int cnt, alloc, term;
+ struct strbuf line = STRBUF_INIT;
+
+ if (!append_stdin)
+ return get_pathspec(prefix, argv);
+
+ for (cnt = 0; argv[cnt]; cnt++)
+ ; /* first count */
+ alloc = alloc_nr(cnt);
+ nargv = xmalloc(sizeof(*nargv) * alloc);
+ for (cnt = 0; argv[cnt]; cnt++)
+ nargv[cnt] = argv[cnt]; /* then copy */
+
+ term = (append_stdin == APPEND_STDIN_Z) ? '\0' : '\n';
+ while (strbuf_getline(&line, stdin, term) != EOF) {
+ ALLOC_GROW(nargv, cnt, alloc);
+ nargv[cnt++] = strbuf_detach(&line, NULL);
+ }
+ ALLOC_GROW(nargv, cnt, alloc);
+ nargv[cnt] = NULL;
+ return get_pathspec(prefix, nargv);
+}
+
/*
* Parse revision information, filling in the "rev_info" structure,
* and removing the used arguments from the argument list.
@@ -1228,17 +1260,26 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,
int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)
{
int i, flags, left, seen_dashdash;
+ enum append_stdin_mode append_stdin = 0;
- /* First, search for "--" */
+ /* First, search for "--", "--stdin-paths", and "--stdin-paths-z" */
seen_dashdash = 0;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
+
+ if (!strcmp(arg, "--stdin-paths"))
+ append_stdin = APPEND_STDIN;
+ else if (!strcmp(arg, "--stdin-paths-z"))
+ append_stdin = APPEND_STDIN_Z;
+
if (strcmp(arg, "--"))
continue;
argv[i] = NULL;
argc = i;
if (argv[i + 1])
- revs->prune_data = get_pathspec(revs->prefix, argv + i + 1);
+ revs->prune_data = grab_pathspec(revs->prefix,
+ argv + i + 1,
+ append_stdin);
seen_dashdash = 1;
break;
}
@@ -1283,6 +1324,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->no_walk = 0;
continue;
}
+ if (!strcmp(arg, "--stdin-paths") ||
+ !strcmp(arg, "--stdin-paths-z"))
+ continue; /* already handled */
opts = handle_revision_opt(revs, argc - i, argv + i, &left, argv);
if (opts > 0) {
@@ -1308,12 +1352,19 @@ 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]);
- revs->prune_data = get_pathspec(revs->prefix,
- argv + i);
+ revs->prune_data = grab_pathspec(revs->prefix,
+ argv + i,
+ append_stdin);
break;
}
}
+ if (!revs->prune_data && append_stdin) {
+ const char *empty_argv[1] = { NULL };
+ revs->prune_data = grab_pathspec(revs->prefix, empty_argv,
+ append_stdin);
+ }
+
if (revs->def == NULL)
revs->def = def;
if (revs->show_merge)
^ permalink raw reply related [flat|nested] 2+ messages in thread