rev-parse: add option for absolute or relative path formatting

git rev-parse has several options which print various paths.  Some of
these paths are printed relative to the current working directory, and
some are absolute.

Normally, this is not a problem, but there are times when one wants
paths entirely in one format or another.  This can be done trivially if
the paths are canonical, but canonicalizing paths is not possible on
some shell scripting environments which lack realpath(1) and also in Go,
which lacks functions that properly canonicalize paths on Windows.

To help out the scripter, let's provide an option which turns most of
the paths printed by git rev-parse to be either relative to the current
working directory or absolute and canonical.  Document which options are
affected and which are not so that users are not confused.

This approach is cleaner and tidier than providing duplicates of
existing options which are either relative or absolute.

Note that if the user needs both forms, it is possible to pass an
additional option in the middle of the command line which changes the
behavior of subsequent operations.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
brian m. carlson
2020-12-13 00:25:29 +00:00
committed by Junio C Hamano
parent be6e0daee7
commit fac60b8925
3 changed files with 194 additions and 43 deletions

View File

@@ -3,6 +3,16 @@
test_description='test git rev-parse'
. ./test-lib.sh
test_one () {
dir="$1" &&
expect="$2" &&
shift &&
shift &&
echo "$expect" >expect &&
git -C "$dir" rev-parse "$@" >actual &&
test_cmp expect actual
}
# usage: [options] label is-bare is-inside-git is-inside-work prefix git-dir absolute-git-dir
test_rev_parse () {
d=
@@ -60,7 +70,13 @@ ROOT=$(pwd)
test_expect_success 'setup' '
mkdir -p sub/dir work &&
cp -R .git repo.git
cp -R .git repo.git &&
git checkout -B main &&
test_commit abc &&
git checkout -b side &&
test_commit def &&
git checkout main &&
git worktree add worktree side
'
test_rev_parse toplevel false false true '' .git "$ROOT/.git"
@@ -88,6 +104,45 @@ test_rev_parse -C work -g ../repo.git -b t 'GIT_DIR=../repo.git, core.bare = tru
test_rev_parse -C work -g ../repo.git -b u 'GIT_DIR=../repo.git, core.bare undefined' false false true ''
test_expect_success 'rev-parse --path-format=absolute' '
test_one "." "$ROOT/.git" --path-format=absolute --git-dir &&
test_one "." "$ROOT/.git" --path-format=absolute --git-common-dir &&
test_one "sub/dir" "$ROOT/.git" --path-format=absolute --git-dir &&
test_one "sub/dir" "$ROOT/.git" --path-format=absolute --git-common-dir &&
test_one "worktree" "$ROOT/.git/worktrees/worktree" --path-format=absolute --git-dir &&
test_one "worktree" "$ROOT/.git" --path-format=absolute --git-common-dir &&
test_one "." "$ROOT" --path-format=absolute --show-toplevel &&
test_one "." "$ROOT/.git/objects" --path-format=absolute --git-path objects &&
test_one "." "$ROOT/.git/objects/foo/bar/baz" --path-format=absolute --git-path objects/foo/bar/baz
'
test_expect_success 'rev-parse --path-format=relative' '
test_one "." ".git" --path-format=relative --git-dir &&
test_one "." ".git" --path-format=relative --git-common-dir &&
test_one "sub/dir" "../../.git" --path-format=relative --git-dir &&
test_one "sub/dir" "../../.git" --path-format=relative --git-common-dir &&
test_one "worktree" "../.git/worktrees/worktree" --path-format=relative --git-dir &&
test_one "worktree" "../.git" --path-format=relative --git-common-dir &&
test_one "." "./" --path-format=relative --show-toplevel &&
test_one "." ".git/objects" --path-format=relative --git-path objects &&
test_one "." ".git/objects/foo/bar/baz" --path-format=relative --git-path objects/foo/bar/baz
'
test_expect_success '--path-format=relative does not affect --absolute-git-dir' '
git rev-parse --path-format=relative --absolute-git-dir >actual &&
echo "$ROOT/.git" >expect &&
test_cmp expect actual
'
test_expect_success '--path-format can change in the middle of the command line' '
git rev-parse --path-format=absolute --git-dir --path-format=relative --git-path objects/foo/bar >actual &&
cat >expect <<-EOF &&
$ROOT/.git
.git/objects/foo/bar
EOF
test_cmp expect actual
'
test_expect_success 'git-common-dir from worktree root' '
echo .git >expect &&
git rev-parse --git-common-dir >actual &&