2008-02-21 06:13:13 +08:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='.git file
|
|
|
|
|
|
|
|
Verify that plumbing commands work when .git is a file
|
|
|
|
'
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
objpath() {
|
2013-12-08 13:56:57 +08:00
|
|
|
echo "$1" | sed -e 's|\(..\)|\1/|'
|
2008-02-21 06:13:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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 &&
|
2008-09-30 16:03:55 +08:00
|
|
|
if ! grep "Invalid gitfile format" .err
|
2008-02-21 06:13:13 +08:00
|
|
|
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 &&
|
2008-09-30 16:03:55 +08:00
|
|
|
if ! grep "Not a git repository" .err
|
2008-02-21 06:13:13 +08:00
|
|
|
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 &&
|
2008-07-23 05:17:43 +08:00
|
|
|
test_cmp bar actual
|
2008-02-21 06:13:13 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
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)"
|
|
|
|
'
|
|
|
|
|
setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when ..
Commit d95138e [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 with d95138e. 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 (*).
With d95138e, 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 in d95138e is reverted earlier, and instead we reuse
the solution from c056261 [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 what d95138e tried to fix,
without upsetting git-clone-inside-hooks.
The test from d95138e remains 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>
2015-12-20 15:50:18 +08:00
|
|
|
test_expect_success 'setup_git_dir twice in subdir' '
|
setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR
In the test case, we run setup_git_dir_gently() the first time to read
$GIT_DIR/config so that we can resolve aliases. We'll enter
setup_discovered_git_dir() and may or may not call set_git_dir() near
the end of the function, depending on whether the detected git dir is
".git" or not. This set_git_dir() will set env var $GIT_DIR.
For normal repo, git dir detected via setup_discovered_git_dir() will be
".git", and set_git_dir() is not called. If .git file is used however,
the git dir can't be ".git" and set_git_dir() is called and $GIT_DIR
set. This is the key of this problem.
If we expand an alias (or autocorrect command names), then
setup_git_dir_gently() is run the second time. If $GIT_DIR is not set in
the first run, we run the same setup_discovered_git_dir() as before.
Nothing to see. If it is, however, we'll enter setup_explicit_git_dir()
this time.
This is where the "fun" is. If $GIT_WORK_TREE is not set but
$GIT_DIR is, you are supposed to be at the root level of the
worktree. But if you are in a subdir "foo/bar" (real worktree's top
is "foo"), this rule bites you: your detected worktree is now
"foo/bar", even though the first run correctly detected worktree as
"foo". You get "internal error: work tree has already been set" as a
result.
Bottom line is, when $GIT_DIR is set, $GIT_WORK_TREE should be set too
unless there's no work tree. But setting $GIT_WORK_TREE inside
set_git_dir() may backfire. We don't know at that point if work tree is
already configured by the caller. So set it when work tree is
detected. It does not harm if $GIT_WORK_TREE is set while $GIT_DIR is
not.
Reported-by: Bjørnar Snoksrud <snoksrud@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-26 18:37:35 +08:00
|
|
|
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
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2015-09-28 21:06:12 +08:00
|
|
|
test_expect_success 'enter_repo non-strict mode' '
|
|
|
|
test_create_repo enter_repo &&
|
|
|
|
(
|
|
|
|
cd enter_repo &&
|
|
|
|
test_tick &&
|
|
|
|
test_commit foo &&
|
|
|
|
mv .git .realgit &&
|
|
|
|
echo "gitdir: .realgit" >.git
|
|
|
|
) &&
|
|
|
|
git ls-remote enter_repo >actual &&
|
|
|
|
cat >expected <<-\EOF &&
|
|
|
|
946e985ab20de757ca5b872b16d64e92ff3803a9 HEAD
|
|
|
|
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/heads/master
|
|
|
|
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/tags/foo
|
|
|
|
EOF
|
|
|
|
test_cmp expected actual
|
|
|
|
'
|
|
|
|
|
2015-09-28 21:06:13 +08:00
|
|
|
test_expect_success 'enter_repo linked checkout' '
|
|
|
|
(
|
|
|
|
cd enter_repo &&
|
|
|
|
git worktree add ../foo refs/tags/foo
|
|
|
|
) &&
|
|
|
|
git ls-remote foo >actual &&
|
|
|
|
cat >expected <<-\EOF &&
|
|
|
|
946e985ab20de757ca5b872b16d64e92ff3803a9 HEAD
|
|
|
|
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/heads/master
|
|
|
|
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/tags/foo
|
|
|
|
EOF
|
|
|
|
test_cmp expected actual
|
|
|
|
'
|
|
|
|
|
2015-09-28 21:06:14 +08:00
|
|
|
test_expect_success 'enter_repo strict mode' '
|
|
|
|
git ls-remote --upload-pack="git upload-pack --strict" foo/.git >actual &&
|
|
|
|
cat >expected <<-\EOF &&
|
|
|
|
946e985ab20de757ca5b872b16d64e92ff3803a9 HEAD
|
|
|
|
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/heads/master
|
|
|
|
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/tags/foo
|
|
|
|
EOF
|
|
|
|
test_cmp expected actual
|
|
|
|
'
|
|
|
|
|
2008-02-21 06:13:13 +08:00
|
|
|
test_done
|