Skip to content

Commit

Permalink
Merge branch 'ps/revision-stdin-with-options'
Browse files Browse the repository at this point in the history
The set-up code for the get_revision() API now allows feeding
options like --all and --not in the --stdin mode.

* ps/revision-stdin-with-options:
  revision: handle pseudo-opts in `--stdin` mode
  revision: small readability improvement for reading from stdin
  revision: reorder `read_revisions_from_stdin()`
  • Loading branch information
gitster committed Jul 4, 2023
2 parents 9748a68 + c40f0b7 commit 812907d
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 39 deletions.
9 changes: 5 additions & 4 deletions Documentation/rev-list-options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,11 @@ ifndef::git-rev-list[]
endif::git-rev-list[]

--stdin::
In addition to the '<commit>' listed on the command
line, read them from the standard input. If a `--` separator is
seen, stop reading commits and start reading paths to limit the
result.
In addition to getting arguments from the command line, read
them for standard input as well. This accepts commits and
pseudo-options like `--all` and `--glob=`. When a `--` separator
is seen, the following input is treated as paths and used to
limit the result.

ifdef::git-rev-list[]
--quiet::
Expand Down
82 changes: 48 additions & 34 deletions revision.c
Original file line number Diff line number Diff line change
Expand Up @@ -2198,39 +2198,6 @@ static void read_pathspec_from_stdin(struct strbuf *sb,
strvec_push(prune, sb->buf);
}

static void read_revisions_from_stdin(struct rev_info *revs,
struct strvec *prune)
{
struct strbuf sb;
int seen_dashdash = 0;
int save_warning;

save_warning = warn_on_object_refname_ambiguity;
warn_on_object_refname_ambiguity = 0;

strbuf_init(&sb, 1000);
while (strbuf_getline(&sb, stdin) != EOF) {
int len = sb.len;
if (!len)
break;
if (sb.buf[0] == '-') {
if (len == 2 && sb.buf[1] == '-') {
seen_dashdash = 1;
break;
}
die("options not supported in --stdin mode");
}
if (handle_revision_arg(sb.buf, revs, 0,
REVARG_CANNOT_BE_FILENAME))
die("bad revision '%s'", sb.buf);
}
if (seen_dashdash)
read_pathspec_from_stdin(&sb, prune);

strbuf_release(&sb);
warn_on_object_refname_ambiguity = save_warning;
}

static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)
{
append_grep_pattern(&revs->grep_filter, ptn, "command line", 0, what);
Expand Down Expand Up @@ -2819,6 +2786,53 @@ static int handle_revision_pseudo_opt(struct rev_info *revs,
return 1;
}

static void read_revisions_from_stdin(struct rev_info *revs,
struct strvec *prune,
int *flags)
{
struct strbuf sb;
int seen_dashdash = 0;
int seen_end_of_options = 0;
int save_warning;

save_warning = warn_on_object_refname_ambiguity;
warn_on_object_refname_ambiguity = 0;

strbuf_init(&sb, 1000);
while (strbuf_getline(&sb, stdin) != EOF) {
if (!sb.len)
break;

if (!strcmp(sb.buf, "--")) {
seen_dashdash = 1;
break;
}

if (!seen_end_of_options && sb.buf[0] == '-') {
const char *argv[] = { sb.buf, NULL };

if (!strcmp(sb.buf, "--end-of-options")) {
seen_end_of_options = 1;
continue;
}

if (handle_revision_pseudo_opt(revs, argv, flags) > 0)
continue;

die(_("invalid option '%s' in --stdin mode"), sb.buf);
}

if (handle_revision_arg(sb.buf, revs, 0,
REVARG_CANNOT_BE_FILENAME))
die("bad revision '%s'", sb.buf);
}
if (seen_dashdash)
read_pathspec_from_stdin(&sb, prune);

strbuf_release(&sb);
warn_on_object_refname_ambiguity = save_warning;
}

static void NORETURN diagnose_missing_default(const char *def)
{
int flags;
Expand Down Expand Up @@ -2891,7 +2905,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
}
if (revs->read_from_stdin++)
die("--stdin given twice?");
read_revisions_from_stdin(revs, &prune_data);
read_revisions_from_stdin(revs, &prune_data, &flags);
continue;
}

Expand Down
51 changes: 50 additions & 1 deletion t/t6017-rev-list-stdin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ test_expect_success setup '
git add file-$i &&
test_tick &&
git commit -m side-$i || exit
done
done &&
git update-ref refs/heads/-dashed-branch HEAD
)
'

Expand All @@ -60,6 +62,12 @@ 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
check --all
check --all --not --branches
check --glob=refs/heads
check --glob=refs/heads --
check --glob=refs/heads -- file-1
check --end-of-options -dashed-branch

test_expect_success 'not only --stdin' '
cat >expect <<-EOF &&
Expand All @@ -78,4 +86,45 @@ test_expect_success 'not only --stdin' '
test_cmp expect actual
'

test_expect_success 'pseudo-opt with missing value' '
cat >input <<-EOF &&
--glob
refs/heads
EOF
cat >expect <<-EOF &&
fatal: Option ${SQ}--glob${SQ} requires a value
EOF
test_must_fail git rev-list --stdin <input 2>error &&
test_cmp expect error
'

test_expect_success 'pseudo-opt with invalid value' '
cat >input <<-EOF &&
--no-walk=garbage
EOF
cat >expect <<-EOF &&
error: invalid argument to --no-walk
fatal: invalid option ${SQ}--no-walk=garbage${SQ} in --stdin mode
EOF
test_must_fail git rev-list --stdin <input 2>error &&
test_cmp expect error
'

test_expect_success 'unknown option without --end-of-options' '
cat >input <<-EOF &&
-dashed-branch
EOF
cat >expect <<-EOF &&
fatal: invalid option ${SQ}-dashed-branch${SQ} in --stdin mode
EOF
test_must_fail git rev-list --stdin <input 2>error &&
test_cmp expect error
'

test_done

0 comments on commit 812907d

Please sign in to comment.