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 <gitster@pobox.com>
Junio C Hamano committed
Nov 20, 2009 at 02:50 UTC
60da8b15c1b77706e0701cccef2d534a1c3825ad
2 files changed
+71
-5
Documentation/rev-list-options.txt
+3
-1
@@ -246,7 +246,9 @@ endif::git-rev-list[]
246
--stdin::
247
248
In addition to the '<commit>' listed on the command
249
- line, read them from the standard input.
249
+ line, read them from the standard input. If a '--' separator is
250
+ seen, stop reading commits and start reading paths to limit the
251
+ result.
252
253
ifdef::git-rev-list[]
254
--quiet::
revision.c
+68
-4
@@ -953,9 +953,38 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
953
return 0;
954
}
955
956
-static void read_revisions_from_stdin(struct rev_info *revs)
956
+static void read_pathspec_from_stdin(struct rev_info *revs, struct strbuf *sb, const char ***prune_data)
957
+{
958
+ const char **prune = *prune_data;
959
+ int prune_nr;
960
+ int prune_alloc;
961
+
962
+ /* count existing ones */
963
+ if (!prune)
964
+ prune_nr = 0;
965
+ else
966
+ for (prune_nr = 0; prune[prune_nr]; prune_nr++)
967
+ ;
968
+ prune_alloc = prune_nr; /* not really, but we do not know */
969
+
970
+ while (strbuf_getwholeline(sb, stdin, '\n') != EOF) {
971
+ int len = sb->len;
972
+ if (len && sb->buf[len - 1] == '\n')
973
+ sb->buf[--len] = '\0';
974
+ ALLOC_GROW(prune, prune_nr+1, prune_alloc);
975
+ prune[prune_nr++] = xstrdup(sb->buf);
976
+ }
977
+ if (prune) {
978
+ ALLOC_GROW(prune, prune_nr+1, prune_alloc);
979
+ prune[prune_nr] = NULL;
980
+ }
981
+ *prune_data = prune;
982
+}
983
+
984
+static void read_revisions_from_stdin(struct rev_info *revs, const char ***prune)
985
{
986
struct strbuf sb;
987
+ int seen_dashdash = 0;
988
989
strbuf_init(&sb, 1000);
990
while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) {
@@ -964,11 +993,18 @@ static void read_revisions_from_stdin(struct rev_info *revs)
993
sb.buf[--len] = '\0';
994
if (!len)
995
break;
967
- if (sb.buf[0] == '-')
996
+ if (sb.buf[0] == '-') {
997
+ if (len == 2 && sb.buf[1] == '-') {
998
+ seen_dashdash = 1;
999
+ break;
1000
+ }
1001
die("options not supported in --stdin mode");
1002
+ }
1003
if (handle_revision_arg(sb.buf, revs, 0, 1))
1004
die("bad revision '%s'", sb.buf);
1005
}
1006
+ if (seen_dashdash)
1007
+ read_pathspec_from_stdin(revs, &sb, prune);
1008
strbuf_release(&sb);
1009
}
1010
@@ -1220,6 +1256,34 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,
1256
ctx->argc -= n;
1257
}
1258
1259
+static void append_prune_data(const char ***prune_data, const char **av)
1260
+{
1261
+ const char **prune = *prune_data;
1262
+ int prune_nr;
1263
+ int prune_alloc;
1264
+
1265
+ if (!prune) {
1266
+ *prune_data = av;
1267
+ return;
1268
+ }
1269
+
1270
+ /* count existing ones */
1271
+ for (prune_nr = 0; prune[prune_nr]; prune_nr++)
1272
+ ;
1273
+ prune_alloc = prune_nr; /* not really, but we do not know */
1274
+
1275
+ while (*av) {
1276
+ ALLOC_GROW(prune, prune_nr+1, prune_alloc);
1277
+ prune[prune_nr++] = *av;
1278
+ av++;
1279
+ }
1280
+ if (prune) {
1281
+ ALLOC_GROW(prune, prune_nr+1, prune_alloc);
1282
+ prune[prune_nr] = NULL;
1283
+ }
1284
+ *prune_data = prune;
1285
+}
1286
+
1287
/*
1288
* Parse revision information, filling in the "rev_info" structure,
1289
* 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
1358
}
1359
if (read_from_stdin++)
1360
die("--stdin given twice?");
1297
- read_revisions_from_stdin(revs);
1361
+ read_revisions_from_stdin(revs, &prune_data);
1362
continue;
1363
}
1364
@@ -1322,7 +1386,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
1386
for (j = i; j < argc; j++)
1387
verify_filename(revs->prefix, argv[j]);
1388
1325
- prune_data = argv + i;
1389
+ append_prune_data(&prune_data, argv + i);
1390
break;
1391
}
1392
}