git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Q: supplying large sets of path to git commands
@ 2009-10-16 10:40 Constantine Plotnikov
  2009-10-16 22:08 ` Junio C Hamano
  0 siblings, 1 reply; 2+ messages in thread
From: Constantine Plotnikov @ 2009-10-16 10:40 UTC (permalink / raw)
  To: Git Mailing List

Some git commands like git check-attr supports receiving paths from
stdin. For other commands like "git diff" and "git commit --only" I
have not found a way to supply a lot of paths (say 1000). Is there a
standard way pass a additional paths to git commands that works on
windows and unix? It would be nice to have --stdin option for all
commands that might receive a set of paths. Or even better would
something like "--options-from-stdin" and
"--options-from-file=file.txt" as a possible last argument specified
on the command line.

Constantine

^ permalink raw reply	[flat|nested] 2+ messages in thread

* 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

end of thread, other threads:[~2009-10-16 22:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-16 10:40 Q: supplying large sets of path to git commands Constantine Plotnikov
2009-10-16 22:08 ` Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).