Skip to content

Commit 60da8b1

Browse files
committed
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>
1 parent 5486ef0 commit 60da8b1

File tree

2 files changed

+71
-5
lines changed

2 files changed

+71
-5
lines changed

Documentation/rev-list-options.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,9 @@ endif::git-rev-list[]
246246
--stdin::
247247

248248
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.
250252

251253
ifdef::git-rev-list[]
252254
--quiet::

revision.c

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -953,9 +953,38 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
953953
return 0;
954954
}
955955

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)
957985
{
958986
struct strbuf sb;
987+
int seen_dashdash = 0;
959988

960989
strbuf_init(&sb, 1000);
961990
while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) {
@@ -964,11 +993,18 @@ static void read_revisions_from_stdin(struct rev_info *revs)
964993
sb.buf[--len] = '\0';
965994
if (!len)
966995
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+
}
9681001
die("options not supported in --stdin mode");
1002+
}
9691003
if (handle_revision_arg(sb.buf, revs, 0, 1))
9701004
die("bad revision '%s'", sb.buf);
9711005
}
1006+
if (seen_dashdash)
1007+
read_pathspec_from_stdin(revs, &sb, prune);
9721008
strbuf_release(&sb);
9731009
}
9741010

@@ -1220,6 +1256,34 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,
12201256
ctx->argc -= n;
12211257
}
12221258

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+
12231287
/*
12241288
* Parse revision information, filling in the "rev_info" structure,
12251289
* 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
12941358
}
12951359
if (read_from_stdin++)
12961360
die("--stdin given twice?");
1297-
read_revisions_from_stdin(revs);
1361+
read_revisions_from_stdin(revs, &prune_data);
12981362
continue;
12991363
}
13001364

@@ -1322,7 +1386,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
13221386
for (j = i; j < argc; j++)
13231387
verify_filename(revs->prefix, argv[j]);
13241388

1325-
prune_data = argv + i;
1389+
append_prune_data(&prune_data, argv + i);
13261390
break;
13271391
}
13281392
}

0 commit comments

Comments
 (0)