Skip to content

Commit 7488c2f

Browse files
committed
Merge branch 'jk/rev-parse-local-env-vars' into maint
The "--local-env-vars" and "--resolve-git-dir" options of "git rev-parse" failed to work outside a repository when the command's option parsing was rewritten in 1.8.5 era. * jk/rev-parse-local-env-vars: rev-parse: let some options run outside repository t1515: add tests for rev-parse out-of-repo helpers
2 parents 0759dfd + fc7d47f commit 7488c2f

File tree

2 files changed

+77
-18
lines changed

2 files changed

+77
-18
lines changed

builtin/rev-parse.c

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ N_("git rev-parse --parseopt [<options>] -- [<args>...]\n"
505505
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
506506
{
507507
int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
508+
int did_repo_setup = 0;
508509
int has_dashdash = 0;
509510
int output_prefix = 0;
510511
unsigned char sha1[20];
@@ -528,11 +529,40 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
528529
}
529530
}
530531

531-
prefix = setup_git_directory();
532-
git_config(git_default_config, NULL);
532+
/* No options; just report on whether we're in a git repo or not. */
533+
if (argc == 1) {
534+
setup_git_directory();
535+
git_config(git_default_config, NULL);
536+
return 0;
537+
}
538+
533539
for (i = 1; i < argc; i++) {
534540
const char *arg = argv[i];
535541

542+
if (!strcmp(arg, "--local-env-vars")) {
543+
int i;
544+
for (i = 0; local_repo_env[i]; i++)
545+
printf("%s\n", local_repo_env[i]);
546+
continue;
547+
}
548+
if (!strcmp(arg, "--resolve-git-dir")) {
549+
const char *gitdir = argv[++i];
550+
if (!gitdir)
551+
die("--resolve-git-dir requires an argument");
552+
gitdir = resolve_gitdir(gitdir);
553+
if (!gitdir)
554+
die("not a gitdir '%s'", argv[i]);
555+
puts(gitdir);
556+
continue;
557+
}
558+
559+
/* The rest of the options require a git repository. */
560+
if (!did_repo_setup) {
561+
prefix = setup_git_directory();
562+
git_config(git_default_config, NULL);
563+
did_repo_setup = 1;
564+
}
565+
536566
if (!strcmp(arg, "--git-path")) {
537567
if (!argv[i + 1])
538568
die("--git-path requires an argument");
@@ -706,12 +736,6 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
706736
add_ref_exclusion(&ref_excludes, arg + 10);
707737
continue;
708738
}
709-
if (!strcmp(arg, "--local-env-vars")) {
710-
int i;
711-
for (i = 0; local_repo_env[i]; i++)
712-
printf("%s\n", local_repo_env[i]);
713-
continue;
714-
}
715739
if (!strcmp(arg, "--show-toplevel")) {
716740
const char *work_tree = get_git_work_tree();
717741
if (work_tree)
@@ -767,16 +791,6 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
767791
puts(prefix_filename(pfx, strlen(pfx), get_git_common_dir()));
768792
continue;
769793
}
770-
if (!strcmp(arg, "--resolve-git-dir")) {
771-
const char *gitdir = argv[++i];
772-
if (!gitdir)
773-
die("--resolve-git-dir requires an argument");
774-
gitdir = resolve_gitdir(gitdir);
775-
if (!gitdir)
776-
die("not a gitdir '%s'", argv[i]);
777-
puts(gitdir);
778-
continue;
779-
}
780794
if (!strcmp(arg, "--is-inside-git-dir")) {
781795
printf("%s\n", is_inside_git_dir() ? "true"
782796
: "false");

t/t1515-rev-parse-outside-repo.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/sh
2+
3+
test_description='check that certain rev-parse options work outside repo'
4+
. ./test-lib.sh
5+
6+
test_expect_success 'set up non-repo directory' '
7+
GIT_CEILING_DIRECTORIES=$(pwd) &&
8+
export GIT_CEILING_DIRECTORIES &&
9+
mkdir non-repo &&
10+
cd non-repo &&
11+
# confirm that git does not find a repo
12+
test_must_fail git rev-parse --git-dir
13+
'
14+
15+
# Rather than directly test the output of sq-quote directly,
16+
# make sure the shell can read back a tricky case, since
17+
# that's what we really care about anyway.
18+
tricky="really tricky with \\ and \" and '"
19+
dump_args () {
20+
for i in "$@"; do
21+
echo "arg: $i"
22+
done
23+
}
24+
test_expect_success 'rev-parse --sq-quote' '
25+
dump_args "$tricky" easy >expect &&
26+
eval "dump_args $(git rev-parse --sq-quote "$tricky" easy)" >actual &&
27+
test_cmp expect actual
28+
'
29+
30+
test_expect_success 'rev-parse --local-env-vars' '
31+
git rev-parse --local-env-vars >actual &&
32+
# we do not want to depend on the complete list here,
33+
# so just look for something plausible
34+
grep ^GIT_DIR actual
35+
'
36+
37+
test_expect_success 'rev-parse --resolve-git-dir' '
38+
git init --separate-git-dir repo dir &&
39+
test_must_fail git rev-parse --resolve-git-dir . &&
40+
echo "$(pwd)/repo" >expect &&
41+
git rev-parse --resolve-git-dir dir/.git >actual &&
42+
test_cmp expect actual
43+
'
44+
45+
test_done

0 commit comments

Comments
 (0)