Skip to content

Commit a2f5a87

Browse files
szedergitster
authored andcommitted
rev-parse: add '--absolute-git-dir' option
The output of 'git rev-parse --git-dir' can be either a relative or an absolute path, depending on whether the current working directory is at the top of the worktree or the .git directory or not, or how the path to the repository is specified via the '--git-dir=<path>' option or the $GIT_DIR environment variable. And if that output is a relative path, then it is relative to the directory where any 'git -C <path>' options might have led us. This doesn't matter at all for regular scripts, because the git wrapper automatically takes care of changing directories according to the '-C <path>' options, and the scripts can then simply follow any path returned by 'git rev-parse --git-dir', even if it's a relative path. Our Bash completion script, however, is unique in that it must run directly in the user's interactive shell environment. This means that it's not executed through the git wrapper and would have to take care of any '-C <path> options on its own, and it can't just change directories as it pleases. Consequently, adding support for taking any '-C <path>' options on the command line into account during completion turned out to be considerably more difficult, error prone and required more subshells and git processes when it had to cope with a relative path to the .git directory. Help this rather special use case and teach 'git rev-parse' a new '--absolute-git-dir' option which always outputs a canonicalized absolute path to the .git directory, regardless of whether the path is discovered automatically or is specified via $GIT_DIR or 'git --git-dir=<path>'. Signed-off-by: SZEDER Gábor <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 336d694 commit a2f5a87

File tree

3 files changed

+31
-16
lines changed

3 files changed

+31
-16
lines changed

Documentation/git-rev-parse.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ If `$GIT_DIR` is not defined and the current directory
217217
is not detected to lie in a Git repository or work tree
218218
print a message to stderr and exit with nonzero status.
219219

220+
--absolute-git-dir::
221+
Like `--git-dir`, but its output is always the canonicalized
222+
absolute path.
223+
220224
--git-common-dir::
221225
Show `$GIT_COMMON_DIR` if defined, else `$GIT_DIR`.
222226

builtin/rev-parse.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -802,17 +802,27 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
802802
putchar('\n');
803803
continue;
804804
}
805-
if (!strcmp(arg, "--git-dir")) {
805+
if (!strcmp(arg, "--git-dir") ||
806+
!strcmp(arg, "--absolute-git-dir")) {
806807
const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
807808
char *cwd;
808809
int len;
809-
if (gitdir) {
810-
puts(gitdir);
811-
continue;
812-
}
813-
if (!prefix) {
814-
puts(".git");
815-
continue;
810+
if (arg[2] == 'g') { /* --git-dir */
811+
if (gitdir) {
812+
puts(gitdir);
813+
continue;
814+
}
815+
if (!prefix) {
816+
puts(".git");
817+
continue;
818+
}
819+
} else { /* --absolute-git-dir */
820+
if (!gitdir && !prefix)
821+
gitdir = ".git";
822+
if (gitdir) {
823+
puts(real_path(gitdir));
824+
continue;
825+
}
816826
}
817827
cwd = xgetcwd();
818828
len = strlen(cwd);

t/t1500-rev-parse.sh

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
test_description='test git rev-parse'
44
. ./test-lib.sh
55

6-
# usage: [options] label is-bare is-inside-git is-inside-work prefix git-dir
6+
# usage: [options] label is-bare is-inside-git is-inside-work prefix git-dir absolute-git-dir
77
test_rev_parse () {
88
d=
99
bare=
@@ -29,7 +29,8 @@ test_rev_parse () {
2929
--is-inside-git-dir \
3030
--is-inside-work-tree \
3131
--show-prefix \
32-
--git-dir
32+
--git-dir \
33+
--absolute-git-dir
3334
do
3435
test $# -eq 0 && break
3536
expect="$1"
@@ -62,26 +63,26 @@ test_expect_success 'setup' '
6263
cp -R .git repo.git
6364
'
6465

65-
test_rev_parse toplevel false false true '' .git
66+
test_rev_parse toplevel false false true '' .git "$ROOT/.git"
6667

67-
test_rev_parse -C .git .git/ false true false '' .
68-
test_rev_parse -C .git/objects .git/objects/ false true false '' "$ROOT/.git"
68+
test_rev_parse -C .git .git/ false true false '' . "$ROOT/.git"
69+
test_rev_parse -C .git/objects .git/objects/ false true false '' "$ROOT/.git" "$ROOT/.git"
6970

70-
test_rev_parse -C sub/dir subdirectory false false true sub/dir/ "$ROOT/.git"
71+
test_rev_parse -C sub/dir subdirectory false false true sub/dir/ "$ROOT/.git" "$ROOT/.git"
7172

7273
test_rev_parse -b t 'core.bare = true' true false false
7374

7475
test_rev_parse -b u 'core.bare undefined' false false true
7576

7677

77-
test_rev_parse -C work -g ../.git -b f 'GIT_DIR=../.git, core.bare = false' false false true ''
78+
test_rev_parse -C work -g ../.git -b f 'GIT_DIR=../.git, core.bare = false' false false true '' "../.git" "$ROOT/.git"
7879

7980
test_rev_parse -C work -g ../.git -b t 'GIT_DIR=../.git, core.bare = true' true false false ''
8081

8182
test_rev_parse -C work -g ../.git -b u 'GIT_DIR=../.git, core.bare undefined' false false true ''
8283

8384

84-
test_rev_parse -C work -g ../repo.git -b f 'GIT_DIR=../repo.git, core.bare = false' false false true ''
85+
test_rev_parse -C work -g ../repo.git -b f 'GIT_DIR=../repo.git, core.bare = false' false false true '' "../repo.git" "$ROOT/repo.git"
8586

8687
test_rev_parse -C work -g ../repo.git -b t 'GIT_DIR=../repo.git, core.bare = true' true false false ''
8788

0 commit comments

Comments
 (0)