Browse Source

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
maint
Junio C Hamano 15 years ago
parent
commit
e61f25f3a6
  1. 6
      Documentation/rev-list-options.txt
  2. 1
      builtin-blame.c
  3. 1
      builtin-diff-tree.c
  4. 7
      builtin-rev-list.c
  5. 12
      bundle.c
  6. 106
      revision.c
  7. 4
      revision.h
  8. 61
      t/t6017-rev-list-stdin.sh

6
Documentation/rev-list-options.txt

@ -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

1
builtin-blame.c

@ -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));



1
builtin-diff-tree.c

@ -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) {

7
builtin-rev-list.c

@ -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

@ -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

@ -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)

4
revision.h

@ -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

@ -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…
Cancel
Save