mirror of
https://github.com/git/git.git
synced 2025-03-13 20:15:19 +00:00
Merge branch 'jc/log-stdin'
* jc/log-stdin: Add trivial tests for --stdin option to log family Make --stdin option to "log" family read also pathspecs setup_revisions(): do not call get_pathspec() too early Teach --stdin option to "log" family read_revision_from_stdin(): use strbuf Conflicts: revision.c
This commit is contained in:
commit
e61f25f3a6
@ -243,12 +243,14 @@ endif::git-rev-list[]
|
|||||||
Pretend as if all the refs in `$GIT_DIR/refs/remotes` are listed
|
Pretend as if all the refs in `$GIT_DIR/refs/remotes` are listed
|
||||||
on the command line as '<commit>'.
|
on the command line as '<commit>'.
|
||||||
|
|
||||||
ifdef::git-rev-list[]
|
|
||||||
--stdin::
|
--stdin::
|
||||||
|
|
||||||
In addition to the '<commit>' listed on the command
|
In addition to the '<commit>' listed on the command
|
||||||
line, read them from the standard input.
|
line, read them from the standard input. If a '--' separator is
|
||||||
|
seen, stop reading commits and start reading paths to limit the
|
||||||
|
result.
|
||||||
|
|
||||||
|
ifdef::git-rev-list[]
|
||||||
--quiet::
|
--quiet::
|
||||||
|
|
||||||
Don't print anything to standard output. This form
|
Don't print anything to standard output. This form
|
||||||
|
@ -2358,6 +2358,7 @@ parse_done:
|
|||||||
die_errno("cannot stat path '%s'", path);
|
die_errno("cannot stat path '%s'", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
revs.disable_stdin = 1;
|
||||||
setup_revisions(argc, argv, &revs, NULL);
|
setup_revisions(argc, argv, &revs, NULL);
|
||||||
memset(&sb, 0, sizeof(sb));
|
memset(&sb, 0, sizeof(sb));
|
||||||
|
|
||||||
|
@ -104,6 +104,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
|
|||||||
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
|
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
|
||||||
opt->abbrev = 0;
|
opt->abbrev = 0;
|
||||||
opt->diff = 1;
|
opt->diff = 1;
|
||||||
|
opt->disable_stdin = 1;
|
||||||
argc = setup_revisions(argc, argv, opt, NULL);
|
argc = setup_revisions(argc, argv, opt, NULL);
|
||||||
|
|
||||||
while (--argc > 0) {
|
while (--argc > 0) {
|
||||||
|
@ -306,7 +306,6 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
|||||||
struct rev_info revs;
|
struct rev_info revs;
|
||||||
struct rev_list_info info;
|
struct rev_list_info info;
|
||||||
int i;
|
int i;
|
||||||
int read_from_stdin = 0;
|
|
||||||
int bisect_list = 0;
|
int bisect_list = 0;
|
||||||
int bisect_show_vars = 0;
|
int bisect_show_vars = 0;
|
||||||
int bisect_find_all = 0;
|
int bisect_find_all = 0;
|
||||||
@ -351,12 +350,6 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
|||||||
bisect_show_vars = 1;
|
bisect_show_vars = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(arg, "--stdin")) {
|
|
||||||
if (read_from_stdin++)
|
|
||||||
die("--stdin given twice?");
|
|
||||||
read_revisions_from_stdin(&revs);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
usage(rev_list_usage);
|
usage(rev_list_usage);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
12
bundle.c
12
bundle.c
@ -204,7 +204,6 @@ int create_bundle(struct bundle_header *header, const char *path,
|
|||||||
int i, ref_count = 0;
|
int i, ref_count = 0;
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
struct rev_info revs;
|
struct rev_info revs;
|
||||||
int read_from_stdin = 0;
|
|
||||||
struct child_process rls;
|
struct child_process rls;
|
||||||
FILE *rls_fout;
|
FILE *rls_fout;
|
||||||
|
|
||||||
@ -256,15 +255,8 @@ int create_bundle(struct bundle_header *header, const char *path,
|
|||||||
/* write references */
|
/* write references */
|
||||||
argc = setup_revisions(argc, argv, &revs, NULL);
|
argc = setup_revisions(argc, argv, &revs, NULL);
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
if (argc > 1)
|
||||||
if (!strcmp(argv[i], "--stdin")) {
|
return error("unrecognized argument: %s'", argv[1]);
|
||||||
if (read_from_stdin++)
|
|
||||||
die("--stdin given twice?");
|
|
||||||
read_revisions_from_stdin(&revs);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return error("unrecognized argument: %s'", argv[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
object_array_remove_duplicates(&revs.pending);
|
object_array_remove_duplicates(&revs.pending);
|
||||||
|
|
||||||
|
106
revision.c
106
revision.c
@ -953,21 +953,59 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_revisions_from_stdin(struct rev_info *revs)
|
static void read_pathspec_from_stdin(struct rev_info *revs, struct strbuf *sb, const char ***prune_data)
|
||||||
{
|
{
|
||||||
char line[1000];
|
const char **prune = *prune_data;
|
||||||
|
int prune_nr;
|
||||||
|
int prune_alloc;
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), stdin) != NULL) {
|
/* count existing ones */
|
||||||
int len = strlen(line);
|
if (!prune)
|
||||||
if (len && line[len - 1] == '\n')
|
prune_nr = 0;
|
||||||
line[--len] = '\0';
|
else
|
||||||
|
for (prune_nr = 0; prune[prune_nr]; prune_nr++)
|
||||||
|
;
|
||||||
|
prune_alloc = prune_nr; /* not really, but we do not know */
|
||||||
|
|
||||||
|
while (strbuf_getwholeline(sb, stdin, '\n') != EOF) {
|
||||||
|
int len = sb->len;
|
||||||
|
if (len && sb->buf[len - 1] == '\n')
|
||||||
|
sb->buf[--len] = '\0';
|
||||||
|
ALLOC_GROW(prune, prune_nr+1, prune_alloc);
|
||||||
|
prune[prune_nr++] = xstrdup(sb->buf);
|
||||||
|
}
|
||||||
|
if (prune) {
|
||||||
|
ALLOC_GROW(prune, prune_nr+1, prune_alloc);
|
||||||
|
prune[prune_nr] = NULL;
|
||||||
|
}
|
||||||
|
*prune_data = prune;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void read_revisions_from_stdin(struct rev_info *revs, const char ***prune)
|
||||||
|
{
|
||||||
|
struct strbuf sb;
|
||||||
|
int seen_dashdash = 0;
|
||||||
|
|
||||||
|
strbuf_init(&sb, 1000);
|
||||||
|
while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) {
|
||||||
|
int len = sb.len;
|
||||||
|
if (len && sb.buf[len - 1] == '\n')
|
||||||
|
sb.buf[--len] = '\0';
|
||||||
if (!len)
|
if (!len)
|
||||||
break;
|
break;
|
||||||
if (line[0] == '-')
|
if (sb.buf[0] == '-') {
|
||||||
|
if (len == 2 && sb.buf[1] == '-') {
|
||||||
|
seen_dashdash = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
die("options not supported in --stdin mode");
|
die("options not supported in --stdin mode");
|
||||||
if (handle_revision_arg(line, revs, 0, 1))
|
}
|
||||||
die("bad revision '%s'", line);
|
if (handle_revision_arg(sb.buf, revs, 0, 1))
|
||||||
|
die("bad revision '%s'", sb.buf);
|
||||||
}
|
}
|
||||||
|
if (seen_dashdash)
|
||||||
|
read_pathspec_from_stdin(revs, &sb, prune);
|
||||||
|
strbuf_release(&sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)
|
static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)
|
||||||
@ -1229,6 +1267,34 @@ static int for_each_good_bisect_ref(each_ref_fn fn, void *cb_data)
|
|||||||
return for_each_ref_in("refs/bisect/good", fn, cb_data);
|
return for_each_ref_in("refs/bisect/good", fn, cb_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void append_prune_data(const char ***prune_data, const char **av)
|
||||||
|
{
|
||||||
|
const char **prune = *prune_data;
|
||||||
|
int prune_nr;
|
||||||
|
int prune_alloc;
|
||||||
|
|
||||||
|
if (!prune) {
|
||||||
|
*prune_data = av;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* count existing ones */
|
||||||
|
for (prune_nr = 0; prune[prune_nr]; prune_nr++)
|
||||||
|
;
|
||||||
|
prune_alloc = prune_nr; /* not really, but we do not know */
|
||||||
|
|
||||||
|
while (*av) {
|
||||||
|
ALLOC_GROW(prune, prune_nr+1, prune_alloc);
|
||||||
|
prune[prune_nr++] = *av;
|
||||||
|
av++;
|
||||||
|
}
|
||||||
|
if (prune) {
|
||||||
|
ALLOC_GROW(prune, prune_nr+1, prune_alloc);
|
||||||
|
prune[prune_nr] = NULL;
|
||||||
|
}
|
||||||
|
*prune_data = prune;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse revision information, filling in the "rev_info" structure,
|
* Parse revision information, filling in the "rev_info" structure,
|
||||||
* and removing the used arguments from the argument list.
|
* and removing the used arguments from the argument list.
|
||||||
@ -1238,7 +1304,8 @@ static int for_each_good_bisect_ref(each_ref_fn fn, void *cb_data)
|
|||||||
*/
|
*/
|
||||||
int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)
|
int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)
|
||||||
{
|
{
|
||||||
int i, flags, left, seen_dashdash;
|
int i, flags, left, seen_dashdash, read_from_stdin;
|
||||||
|
const char **prune_data = NULL;
|
||||||
|
|
||||||
/* First, search for "--" */
|
/* First, search for "--" */
|
||||||
seen_dashdash = 0;
|
seen_dashdash = 0;
|
||||||
@ -1249,13 +1316,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
|||||||
argv[i] = NULL;
|
argv[i] = NULL;
|
||||||
argc = i;
|
argc = i;
|
||||||
if (argv[i + 1])
|
if (argv[i + 1])
|
||||||
revs->prune_data = get_pathspec(revs->prefix, argv + i + 1);
|
prune_data = argv + i + 1;
|
||||||
seen_dashdash = 1;
|
seen_dashdash = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Second, deal with arguments and options */
|
/* Second, deal with arguments and options */
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
read_from_stdin = 0;
|
||||||
for (left = i = 1; i < argc; i++) {
|
for (left = i = 1; i < argc; i++) {
|
||||||
const char *arg = argv[i];
|
const char *arg = argv[i];
|
||||||
if (*arg == '-') {
|
if (*arg == '-') {
|
||||||
@ -1300,6 +1368,16 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
|||||||
revs->no_walk = 0;
|
revs->no_walk = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(arg, "--stdin")) {
|
||||||
|
if (revs->disable_stdin) {
|
||||||
|
argv[left++] = arg;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (read_from_stdin++)
|
||||||
|
die("--stdin given twice?");
|
||||||
|
read_revisions_from_stdin(revs, &prune_data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
opts = handle_revision_opt(revs, argc - i, argv + i, &left, argv);
|
opts = handle_revision_opt(revs, argc - i, argv + i, &left, argv);
|
||||||
if (opts > 0) {
|
if (opts > 0) {
|
||||||
@ -1325,12 +1403,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
|||||||
for (j = i; j < argc; j++)
|
for (j = i; j < argc; j++)
|
||||||
verify_filename(revs->prefix, argv[j]);
|
verify_filename(revs->prefix, argv[j]);
|
||||||
|
|
||||||
revs->prune_data = get_pathspec(revs->prefix,
|
append_prune_data(&prune_data, argv + i);
|
||||||
argv + i);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prune_data)
|
||||||
|
revs->prune_data = get_pathspec(revs->prefix, prune_data);
|
||||||
|
|
||||||
if (revs->def == NULL)
|
if (revs->def == NULL)
|
||||||
revs->def = def;
|
revs->def = def;
|
||||||
if (revs->show_merge)
|
if (revs->show_merge)
|
||||||
|
@ -84,6 +84,8 @@ struct rev_info {
|
|||||||
use_terminator:1,
|
use_terminator:1,
|
||||||
missing_newline:1,
|
missing_newline:1,
|
||||||
date_mode_explicit:1;
|
date_mode_explicit:1;
|
||||||
|
unsigned int disable_stdin:1;
|
||||||
|
|
||||||
enum date_mode date_mode;
|
enum date_mode date_mode;
|
||||||
|
|
||||||
unsigned int abbrev;
|
unsigned int abbrev;
|
||||||
@ -129,8 +131,6 @@ struct rev_info {
|
|||||||
#define REV_TREE_DIFFERENT 3 /* Mixed changes */
|
#define REV_TREE_DIFFERENT 3 /* Mixed changes */
|
||||||
|
|
||||||
/* revision.c */
|
/* revision.c */
|
||||||
void read_revisions_from_stdin(struct rev_info *revs);
|
|
||||||
|
|
||||||
typedef void (*show_early_output_fn_t)(struct rev_info *, struct commit_list *);
|
typedef void (*show_early_output_fn_t)(struct rev_info *, struct commit_list *);
|
||||||
extern volatile show_early_output_fn_t show_early_output;
|
extern volatile show_early_output_fn_t show_early_output;
|
||||||
|
|
||||||
|
61
t/t6017-rev-list-stdin.sh
Executable file
61
t/t6017-rev-list-stdin.sh
Executable file
@ -0,0 +1,61 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2009, Junio C Hamano
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='log family learns --stdin'
|
||||||
|
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
check () {
|
||||||
|
for cmd in rev-list "log --stat"
|
||||||
|
do
|
||||||
|
for i in "$@"
|
||||||
|
do
|
||||||
|
printf "%s\n" $i
|
||||||
|
done >input &&
|
||||||
|
test_expect_success "check $cmd $*" '
|
||||||
|
git $cmd $(cat input) >expect &&
|
||||||
|
git $cmd --stdin <input >actual &&
|
||||||
|
sed -e "s/^/input /" input &&
|
||||||
|
sed -e "s/^/output /" expect &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
them='1 2 3 4 5 6 7'
|
||||||
|
|
||||||
|
test_expect_success setup '
|
||||||
|
(
|
||||||
|
for i in 0 $them
|
||||||
|
do
|
||||||
|
for j in $them
|
||||||
|
do
|
||||||
|
echo $i.$j >file-$j &&
|
||||||
|
git add file-$j || exit
|
||||||
|
done &&
|
||||||
|
test_tick &&
|
||||||
|
git commit -m $i || exit
|
||||||
|
done &&
|
||||||
|
for i in $them
|
||||||
|
do
|
||||||
|
git checkout -b side-$i master~$i &&
|
||||||
|
echo updated $i >file-$i &&
|
||||||
|
git add file-$i &&
|
||||||
|
test_tick &&
|
||||||
|
git commit -m side-$i || exit
|
||||||
|
done
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
check master
|
||||||
|
check side-1 ^side-4
|
||||||
|
check side-1 ^side-7 --
|
||||||
|
check side-1 ^side-7 -- file-1
|
||||||
|
check side-1 ^side-7 -- file-2
|
||||||
|
check side-3 ^side-4 -- file-3
|
||||||
|
check side-3 ^side-2
|
||||||
|
check side-3 ^side-2 -- file-1
|
||||||
|
|
||||||
|
test_done
|
Loading…
x
Reference in New Issue
Block a user