{"thread":{"id":"21685","subject":"[PATCH 0/3] \"log --stdin\" updates","startedAt":"2009-11-20T11:25:12Z","lastAt":"2009-11-20T17:59:30Z","messageCount":6,"participants":["Junio C Hamano","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"128003","messageId":"1258716315-2213-1-git-send-email-gitster@pobox.com","threadId":"21685","inReplyTo":null,"subject":"[PATCH 0/3] \"log --stdin\" updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-11-20T11:25:12Z","receivedAt":"2009-11-20T11:25:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"These three come on top of 61ab67a (Teach --stdin option to \"log\" family,\n2009-11-03), which gave \"--stdin\" to the log family of commands (e.g. log,\nrev-list).  The earlier patch allowed you to feed only the revs (which was\nwhat gitk originally wanted), but after zero or more revs (one rev per\nline), you can now feed a line that consists of \"--\" and then pathspecs\n(one path per line).\n\nThe whole series probably need to be updated to learn -z option to read\nNUL terminated input.\n\nJunio C Hamano (3):\n  read_revision_from_stdin(): use strbuf\n  setup_revisions(): do not call get_pathspec() too early\n  Make --stdin option to \"log\" family read also pathspecs\n\n revision.c |   95 +++++++++++++++++++++++++++++++++++++++++++++++++++--------\n 1 files changed, 82 insertions(+), 13 deletions(-)\n"},{"id":"128005","messageId":"1258716315-2213-2-git-send-email-gitster@pobox.com","threadId":"21685","inReplyTo":"1258716315-2213-1-git-send-email-gitster@pobox.com","subject":"[PATCH 1/3] read_revision_from_stdin(): use strbuf","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-11-20T11:25:13Z","receivedAt":"2009-11-20T11:25:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"It is so 2005 (and Linus ;-) to have a fixed 1000-byte buffer that\nreads from the user.  Let's use strbuf to unlimit the input length.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n revision.c |   18 ++++++++++--------\n 1 files changed, 10 insertions(+), 8 deletions(-)\n\ndiff --git a/revision.c b/revision.c\nindex 45c5de8..f5b735f 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -955,19 +955,21 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,\n \n static void read_revisions_from_stdin(struct rev_info *revs)\n {\n-\tchar line[1000];\n+\tstruct strbuf sb;\n \n-\twhile (fgets(line, sizeof(line), stdin) != NULL) {\n-\t\tint len = strlen(line);\n-\t\tif (len && line[len - 1] == '\\n')\n-\t\t\tline[--len] = '\\0';\n+\tstrbuf_init(&sb, 1000);\n+\twhile (strbuf_getwholeline(&sb, stdin, '\\n') != EOF) {\n+\t\tint len = sb.len;\n+\t\tif (len && sb.buf[len - 1] == '\\n')\n+\t\t\tsb.buf[--len] = '\\0';\n \t\tif (!len)\n \t\t\tbreak;\n-\t\tif (line[0] == '-')\n+\t\tif (sb.buf[0] == '-')\n \t\t\tdie(\"options not supported in --stdin mode\");\n-\t\tif (handle_revision_arg(line, revs, 0, 1))\n-\t\t\tdie(\"bad revision '%s'\", line);\n+\t\tif (handle_revision_arg(sb.buf, revs, 0, 1))\n+\t\t\tdie(\"bad revision '%s'\", sb.buf);\n \t}\n+\tstrbuf_release(&sb);\n }\n \n static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)\n-- \n1.6.5.3.342.g14bb9\n"},{"id":"128004","messageId":"1258716315-2213-3-git-send-email-gitster@pobox.com","threadId":"21685","inReplyTo":"1258716315-2213-1-git-send-email-gitster@pobox.com","subject":"[PATCH 2/3] setup_revisions(): do not call get_pathspec() too early","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-11-20T11:25:14Z","receivedAt":"2009-11-20T11:25:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This is necessary because in the next patch I'll allow pathspecs to be fed\nfrom the standard input, and pathspecs taken from the command line (and\nconverted via get_pathspec() already) in revs->prune_data too early gets\nin the way when we want to append from the standard input.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n revision.c |    9 ++++++---\n 1 files changed, 6 insertions(+), 3 deletions(-)\n\ndiff --git a/revision.c b/revision.c\nindex f5b735f..4410a45 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1230,6 +1230,7 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,\n int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)\n {\n \tint i, flags, left, seen_dashdash, read_from_stdin;\n+\tconst char **prune_data = NULL;\n \n \t/* First, search for \"--\" */\n \tseen_dashdash = 0;\n@@ -1240,7 +1241,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\targv[i] = NULL;\n \t\targc = i;\n \t\tif (argv[i + 1])\n-\t\t\trevs->prune_data = get_pathspec(revs->prefix, argv + i + 1);\n+\t\t\tprune_data = argv + i + 1;\n \t\tseen_dashdash = 1;\n \t\tbreak;\n \t}\n@@ -1321,12 +1322,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\t\tfor (j = i; j < argc; j++)\n \t\t\t\tverify_filename(revs->prefix, argv[j]);\n \n-\t\t\trevs->prune_data = get_pathspec(revs->prefix,\n-\t\t\t\t\t\t\targv + i);\n+\t\t\tprune_data = argv + i;\n \t\t\tbreak;\n \t\t}\n \t}\n \n+\tif (prune_data)\n+\t\trevs->prune_data = get_pathspec(revs->prefix, prune_data);\n+\n \tif (revs->def == NULL)\n \t\trevs->def = def;\n \tif (revs->show_merge)\n-- \n1.6.5.3.342.g14bb9\n"},{"id":"128006","messageId":"1258716315-2213-4-git-send-email-gitster@pobox.com","threadId":"21685","inReplyTo":"1258716315-2213-1-git-send-email-gitster@pobox.com","subject":"[PATCH 3/3] Make --stdin option to \"log\" family read also pathspecs","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-11-20T11:25:15Z","receivedAt":"2009-11-20T11:25:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Similar to the command line arguments, after giving zero or more revs, you can\nfeed a line \"--\" and then feed pathspecs one at a time.\n\nWith this\n\n\t(\n\t\techo ^maint\n\t\techo --\n\t\techo Documentation\n\t) | git log --stat --oneline --stdin master -- t\n\nlists commits that touch Documentation/ or t/ between maint and master.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n revision.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---\n 1 files changed, 68 insertions(+), 4 deletions(-)\n\ndiff --git a/revision.c b/revision.c\nindex 4410a45..8750c20 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -953,9 +953,38 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,\n \treturn 0;\n }\n \n-static void read_revisions_from_stdin(struct rev_info *revs)\n+static void read_pathspec_from_stdin(struct rev_info *revs, struct strbuf *sb, const char ***prune_data)\n+{\n+\tconst char **prune = *prune_data;\n+\tint prune_nr;\n+\tint prune_alloc;\n+\n+\t/* count existing ones */\n+\tif (!prune)\n+\t\tprune_nr = 0;\n+\telse\n+\t\tfor (prune_nr = 0; prune[prune_nr]; prune_nr++)\n+\t\t\t;\n+\tprune_alloc = prune_nr; /* not really, but we do not know */\n+\n+\twhile (strbuf_getwholeline(sb, stdin, '\\n') != EOF) {\n+\t\tint len = sb->len;\n+\t\tif (len && sb->buf[len - 1] == '\\n')\n+\t\t\tsb->buf[--len] = '\\0';\n+\t\tALLOC_GROW(prune, prune_nr+1, prune_alloc);\n+\t\tprune[prune_nr++] = xstrdup(sb->buf);\n+\t}\n+\tif (prune) {\n+\t\tALLOC_GROW(prune, prune_nr+1, prune_alloc);\n+\t\tprune[prune_nr] = NULL;\n+\t}\n+\t*prune_data = prune;\n+}\n+\n+static void read_revisions_from_stdin(struct rev_info *revs, const char ***prune)\n {\n \tstruct strbuf sb;\n+\tint seen_dashdash = 0;\n \n \tstrbuf_init(&sb, 1000);\n \twhile (strbuf_getwholeline(&sb, stdin, '\\n') != EOF) {\n@@ -964,11 +993,18 @@ static void read_revisions_from_stdin(struct rev_info *revs)\n \t\t\tsb.buf[--len] = '\\0';\n \t\tif (!len)\n \t\t\tbreak;\n-\t\tif (sb.buf[0] == '-')\n+\t\tif (sb.buf[0] == '-') {\n+\t\t\tif (len == 2 && sb.buf[1] == '-') {\n+\t\t\t\tseen_dashdash = 1;\n+\t\t\t\tbreak;\n+\t\t\t}\n \t\t\tdie(\"options not supported in --stdin mode\");\n+\t\t}\n \t\tif (handle_revision_arg(sb.buf, revs, 0, 1))\n \t\t\tdie(\"bad revision '%s'\", sb.buf);\n \t}\n+\tif (seen_dashdash)\n+\t\tread_pathspec_from_stdin(revs, &sb, prune);\n \tstrbuf_release(&sb);\n }\n \n@@ -1220,6 +1256,34 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,\n \tctx->argc -= n;\n }\n \n+static void append_prune_data(const char ***prune_data, const char **av)\n+{\n+\tconst char **prune = *prune_data;\n+\tint prune_nr;\n+\tint prune_alloc;\n+\n+\tif (!prune) {\n+\t\t*prune_data = av;\n+\t\treturn;\n+\t}\n+\n+\t/* count existing ones */\n+\tfor (prune_nr = 0; prune[prune_nr]; prune_nr++)\n+\t\t;\n+\tprune_alloc = prune_nr; /* not really, but we do not know */\n+\n+\twhile (*av) {\n+\t\tALLOC_GROW(prune, prune_nr+1, prune_alloc);\n+\t\tprune[prune_nr++] = *av;\n+\t\tav++;\n+\t}\n+\tif (prune) {\n+\t\tALLOC_GROW(prune, prune_nr+1, prune_alloc);\n+\t\tprune[prune_nr] = NULL;\n+\t}\n+\t*prune_data = prune;\n+}\n+\n /*\n  * Parse revision information, filling in the \"rev_info\" structure,\n  * and removing the used arguments from the argument list.\n@@ -1294,7 +1358,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\t\t\t}\n \t\t\t\tif (read_from_stdin++)\n \t\t\t\t\tdie(\"--stdin given twice?\");\n-\t\t\t\tread_revisions_from_stdin(revs);\n+\t\t\t\tread_revisions_from_stdin(revs, &prune_data);\n \t\t\t\tcontinue;\n \t\t\t}\n \n@@ -1322,7 +1386,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\t\tfor (j = i; j < argc; j++)\n \t\t\t\tverify_filename(revs->prefix, argv[j]);\n \n-\t\t\tprune_data = argv + i;\n+\t\t\tappend_prune_data(&prune_data, argv + i);\n \t\t\tbreak;\n \t\t}\n \t}\n-- \n1.6.5.3.342.g14bb9\n"},{"id":"128019","messageId":"20091120144030.GB5419@coredump.intra.peff.net","threadId":"21685","inReplyTo":"1258716315-2213-1-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 0/3] \"log --stdin\" updates","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-11-20T14:40:30Z","receivedAt":"2009-11-20T14:40:30Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Nov 20, 2009 at 03:25:12AM -0800, Junio C Hamano wrote:\n\n> These three come on top of 61ab67a (Teach --stdin option to \"log\" family,\n> 2009-11-03), which gave \"--stdin\" to the log family of commands (e.g. log,\n> rev-list).  The earlier patch allowed you to feed only the revs (which was\n> what gitk originally wanted), but after zero or more revs (one rev per\n> line), you can now feed a line that consists of \"--\" and then pathspecs\n> (one path per line).\n\nThis looks like a good API feature, though I am curious about the\nmissing \"4/3\" that was the motivation (of course, with a feature\nlike this, it may be for your out-of-git script, but as I said, I am\ncurious :) ). Is it a response to\n\n  http://article.gmane.org/gmane.comp.version-control.git/133268\n\n?\n\nThe implementation looks good from my cursory reading. Tests and docs\nare of course missing. We don't seem to have any rev-list --stdin tests\nalready. Maybe even something as simple as:\n\n  git rev-list HEAD -- file >expect &&\n  (echo HEAD; echo --; echo file) | git rev-list --stdin >actual &&\n  test_cmp expect actual\n\nFor docs, maybe squash this in (it mentions the pathspecs, but also\nloosens --stdin to be available for \"git log\" and friends, which should\nhave been part of 61ab67a).\n\ndiff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt\nindex bf66116..b44fdd9 100644\n--- a/Documentation/rev-list-options.txt\n+++ b/Documentation/rev-list-options.txt\n@@ -243,12 +243,14 @@ endif::git-rev-list[]\n \tPretend as if all the refs in `$GIT_DIR/refs/remotes` are listed\n \ton the command line as '<commit>'.\n \n-ifdef::git-rev-list[]\n --stdin::\n \n \tIn addition to the '<commit>' listed on the command\n-\tline, read them from the standard input.\n+\tline, read them from the standard input. If a '--' separator is\n+\tseen, stop reading commits and start reading paths to limit the\n+\tresult.\n \n+ifdef::git-rev-list[]\n --quiet::\n \n \tDon't print anything to standard output.  This form\n"},{"id":"128031","messageId":"7vws1lvzzx.fsf@alter.siamese.dyndns.org","threadId":"21685","inReplyTo":"20091120144030.GB5419@coredump.intra.peff.net","subject":"Re: [PATCH 0/3] \"log --stdin\" updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-11-20T17:59:30Z","receivedAt":"2009-11-20T17:59:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Fri, Nov 20, 2009 at 03:25:12AM -0800, Junio C Hamano wrote:\n>\n>> These three come on top of 61ab67a (Teach --stdin option to \"log\" family,\n>> 2009-11-03), which gave \"--stdin\" to the log family of commands (e.g. log,\n>> rev-list).  The earlier patch allowed you to feed only the revs (which was\n>> what gitk originally wanted), but after zero or more revs (one rev per\n>> line), you can now feed a line that consists of \"--\" and then pathspecs\n>> (one path per line).\n>\n> This looks like a good API feature, though I am curious about the\n> missing \"4/3\" that was the motivation (of course, with a feature\n> like this, it may be for your out-of-git script, but as I said, I am\n> curious :) ). Is it a response to\n>\n>   http://article.gmane.org/gmane.comp.version-control.git/133268\n>\n> ?\n\nNo.  This series is a follow-up to $gmane/131971; I was suspicious that I\nmissed something for the API feature to be complete back then (and the\npatch was not signed-off partly for that reason), and I found one thing\nthat was lacking.\n"}]}