@matheusbsbs / matheus-bagliano / commits / 60da8b15c1
Fork 0

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 }