Commitd95138e[1] attempted to fix a .git file problem by setting GIT_WORK_TREE whenever GIT_DIR is set. It sounded harmless because we handle GIT_DIR and GIT_WORK_TREE side by side for most commands, with two exceptions: git-init and git-clone. "git clone" is not happy withd95138e. This command ignores GIT_DIR but respects GIT_WORK_TREE [2] [3] which means it used to run fine from a hook, where GIT_DIR was set but GIT_WORK_TREE was not (*). Withd95138e, GIT_WORK_TREE is set all the time and git-clone interprets that as "I give you order to put the worktree here", usually against the user's intention. The solution ind95138eis reverted earlier, and instead we reuse the solution fromc056261[4]. It fixed another setup-messed- up-by-alias by saving and restoring env and spawning a new process, but for git-clone and git-init only. Now we conclude that setup-messed-up-by-alias is always evil. So the env restoration is done for _all_ commands, including external ones, whenever aliases are involved. It fixes whatd95138etried to fix, without upsetting git-clone-inside-hooks. The test fromd95138eremains to verify it's not broken by this. A new test is added to make sure git-clone-inside-hooks remains happy. (*) GIT_WORK_TREE was not set _most of the time_. In some cases GIT_WORK_TREE is set and git-clone will behave differently. The use of GIT_WORK_TREE to direct git-clone to put work tree elsewhere looks like a mistake because it causes surprises this way. But that's a separate story. [1]d95138e(setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR - 2015-06-26) [2]2beebd2(clone: create intermediate directories of destination repo - 2008-06-25) [3]20ccef4(make git-clone GIT_WORK_TREE aware - 2007-07-06) [4]c056261(git potty: restore environments after alias expansion - 2014-06-08) Reported-by: Anthony Sottile <asottile@umich.edu> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
120 lines
2.2 KiB
Bash
Executable File
120 lines
2.2 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='.git file
|
|
|
|
Verify that plumbing commands work when .git is a file
|
|
'
|
|
. ./test-lib.sh
|
|
|
|
objpath() {
|
|
echo "$1" | sed -e 's|\(..\)|\1/|'
|
|
}
|
|
|
|
objck() {
|
|
p=$(objpath "$1")
|
|
if test ! -f "$REAL/objects/$p"
|
|
then
|
|
echo "Object not found: $REAL/objects/$p"
|
|
false
|
|
fi
|
|
}
|
|
|
|
test_expect_success 'initial setup' '
|
|
REAL="$(pwd)/.real" &&
|
|
mv .git "$REAL"
|
|
'
|
|
|
|
test_expect_success 'bad setup: invalid .git file format' '
|
|
echo "gitdir $REAL" >.git &&
|
|
if git rev-parse 2>.err
|
|
then
|
|
echo "git rev-parse accepted an invalid .git file"
|
|
false
|
|
fi &&
|
|
if ! grep "Invalid gitfile format" .err
|
|
then
|
|
echo "git rev-parse returned wrong error"
|
|
false
|
|
fi
|
|
'
|
|
|
|
test_expect_success 'bad setup: invalid .git file path' '
|
|
echo "gitdir: $REAL.not" >.git &&
|
|
if git rev-parse 2>.err
|
|
then
|
|
echo "git rev-parse accepted an invalid .git file path"
|
|
false
|
|
fi &&
|
|
if ! grep "Not a git repository" .err
|
|
then
|
|
echo "git rev-parse returned wrong error"
|
|
false
|
|
fi
|
|
'
|
|
|
|
test_expect_success 'final setup + check rev-parse --git-dir' '
|
|
echo "gitdir: $REAL" >.git &&
|
|
test "$REAL" = "$(git rev-parse --git-dir)"
|
|
'
|
|
|
|
test_expect_success 'check hash-object' '
|
|
echo "foo" >bar &&
|
|
SHA=$(cat bar | git hash-object -w --stdin) &&
|
|
objck $SHA
|
|
'
|
|
|
|
test_expect_success 'check cat-file' '
|
|
git cat-file blob $SHA >actual &&
|
|
test_cmp bar actual
|
|
'
|
|
|
|
test_expect_success 'check update-index' '
|
|
if test -f "$REAL/index"
|
|
then
|
|
echo "Hmm, $REAL/index exists?"
|
|
false
|
|
fi &&
|
|
rm -f "$REAL/objects/$(objpath $SHA)" &&
|
|
git update-index --add bar &&
|
|
if ! test -f "$REAL/index"
|
|
then
|
|
echo "$REAL/index not found"
|
|
false
|
|
fi &&
|
|
objck $SHA
|
|
'
|
|
|
|
test_expect_success 'check write-tree' '
|
|
SHA=$(git write-tree) &&
|
|
objck $SHA
|
|
'
|
|
|
|
test_expect_success 'check commit-tree' '
|
|
SHA=$(echo "commit bar" | git commit-tree $SHA) &&
|
|
objck $SHA
|
|
'
|
|
|
|
test_expect_success 'check rev-list' '
|
|
echo $SHA >"$REAL/HEAD" &&
|
|
test "$SHA" = "$(git rev-list HEAD)"
|
|
'
|
|
|
|
test_expect_success 'setup_git_dir twice in subdir' '
|
|
git init sgd &&
|
|
(
|
|
cd sgd &&
|
|
git config alias.lsfi ls-files &&
|
|
mv .git .realgit &&
|
|
echo "gitdir: .realgit" >.git &&
|
|
mkdir subdir &&
|
|
cd subdir &&
|
|
>foo &&
|
|
git add foo &&
|
|
git lsfi >actual &&
|
|
echo foo >expected &&
|
|
test_cmp expected actual
|
|
)
|
|
'
|
|
|
|
test_done
|