standardize and improve lookup rules for external local repos
When you specify a local repository on the command line of
clone, ls-remote, upload-pack, receive-pack, or upload-archive,
or in a request to git-daemon, we perform a little bit of
lookup magic, doing things like looking in working trees for
.git directories and appending ".git" for bare repos.
For clone, this magic happens in get_repo_path. For
everything else, it happens in enter_repo. In both cases,
there are some ambiguous or confusing cases that aren't
handled well, and there is one case that is not handled the
same by both methods.
This patch tries to provide (and test!) standard, sensible
lookup rules for both code paths. The intended changes are:
1. When looking up "foo", we have always preferred
a working tree "foo" (containing "foo/.git" over the
bare "foo.git". But we did not prefer a bare "foo" over
"foo.git". With this patch, we do so.
2. We would select directories that existed but didn't
actually look like git repositories. With this patch,
we make sure a selected directory looks like a git
repo. Not only is this more sensible in general, but it
will help anybody who is negatively affected by change
(1) negatively (e.g., if they had "foo.git" next to its
separate work tree "foo", and expect to keep finding
"foo.git" when they reference "foo").
3. The enter_repo code path would, given "foo", look for
"foo.git/.git" (i.e., do the ".git" append magic even
for a repo with working tree). The clone code path did
not; with this patch, they now behave the same.
In the unlikely case of a working tree overlaying a bare
repo (i.e., a ".git" directory _inside_ a bare repo), we
continue to treat it as a working tree (prefering the
"inner" .git over the bare repo). This is mainly because the
combination seems nonsensical, and I'd rather stick with
existing behavior on the off chance that somebody is relying
on it.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-03 01:59:13 +04:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='selecting remote repo in ambiguous cases'
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
reset() {
|
|
|
|
rm -rf foo foo.git fetch clone
|
|
|
|
}
|
|
|
|
|
|
|
|
make_tree() {
|
|
|
|
git init "$1" &&
|
|
|
|
(cd "$1" && test_commit "$1")
|
|
|
|
}
|
|
|
|
|
|
|
|
make_bare() {
|
|
|
|
git init --bare "$1" &&
|
|
|
|
(cd "$1" &&
|
2016-01-07 16:51:41 +03:00
|
|
|
tree=$(git hash-object -w -t tree /dev/null) &&
|
standardize and improve lookup rules for external local repos
When you specify a local repository on the command line of
clone, ls-remote, upload-pack, receive-pack, or upload-archive,
or in a request to git-daemon, we perform a little bit of
lookup magic, doing things like looking in working trees for
.git directories and appending ".git" for bare repos.
For clone, this magic happens in get_repo_path. For
everything else, it happens in enter_repo. In both cases,
there are some ambiguous or confusing cases that aren't
handled well, and there is one case that is not handled the
same by both methods.
This patch tries to provide (and test!) standard, sensible
lookup rules for both code paths. The intended changes are:
1. When looking up "foo", we have always preferred
a working tree "foo" (containing "foo/.git" over the
bare "foo.git". But we did not prefer a bare "foo" over
"foo.git". With this patch, we do so.
2. We would select directories that existed but didn't
actually look like git repositories. With this patch,
we make sure a selected directory looks like a git
repo. Not only is this more sensible in general, but it
will help anybody who is negatively affected by change
(1) negatively (e.g., if they had "foo.git" next to its
separate work tree "foo", and expect to keep finding
"foo.git" when they reference "foo").
3. The enter_repo code path would, given "foo", look for
"foo.git/.git" (i.e., do the ".git" append magic even
for a repo with working tree). The clone code path did
not; with this patch, they now behave the same.
In the unlikely case of a working tree overlaying a bare
repo (i.e., a ".git" directory _inside_ a bare repo), we
continue to treat it as a working tree (prefering the
"inner" .git over the bare repo). This is mainly because the
combination seems nonsensical, and I'd rather stick with
existing behavior on the off chance that somebody is relying
on it.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-03 01:59:13 +04:00
|
|
|
commit=$(echo "$1" | git commit-tree $tree) &&
|
|
|
|
git update-ref HEAD $commit
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
get() {
|
|
|
|
git init --bare fetch &&
|
|
|
|
(cd fetch && git fetch "../$1") &&
|
|
|
|
git clone "$1" clone
|
|
|
|
}
|
|
|
|
|
|
|
|
check() {
|
|
|
|
echo "$1" >expect &&
|
|
|
|
(cd fetch && git log -1 --format=%s FETCH_HEAD) >actual.fetch &&
|
|
|
|
(cd clone && git log -1 --format=%s HEAD) >actual.clone &&
|
|
|
|
test_cmp expect actual.fetch &&
|
|
|
|
test_cmp expect actual.clone
|
|
|
|
}
|
|
|
|
|
|
|
|
test_expect_success 'find .git dir in worktree' '
|
|
|
|
reset &&
|
|
|
|
make_tree foo &&
|
|
|
|
get foo &&
|
|
|
|
check foo
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'automagically add .git suffix' '
|
|
|
|
reset &&
|
|
|
|
make_bare foo.git &&
|
|
|
|
get foo &&
|
|
|
|
check foo.git
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'automagically add .git suffix to worktree' '
|
|
|
|
reset &&
|
|
|
|
make_tree foo.git &&
|
|
|
|
get foo &&
|
|
|
|
check foo.git
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'prefer worktree foo over bare foo.git' '
|
|
|
|
reset &&
|
|
|
|
make_tree foo &&
|
|
|
|
make_bare foo.git &&
|
|
|
|
get foo &&
|
|
|
|
check foo
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'prefer bare foo over bare foo.git' '
|
|
|
|
reset &&
|
|
|
|
make_bare foo &&
|
|
|
|
make_bare foo.git &&
|
|
|
|
get foo &&
|
|
|
|
check foo
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'disambiguate with full foo.git' '
|
|
|
|
reset &&
|
|
|
|
make_bare foo &&
|
|
|
|
make_bare foo.git &&
|
|
|
|
get foo.git &&
|
|
|
|
check foo.git
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'we are not fooled by non-git foo directory' '
|
|
|
|
reset &&
|
|
|
|
make_bare foo.git &&
|
|
|
|
mkdir foo &&
|
|
|
|
get foo &&
|
|
|
|
check foo.git
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'prefer inner .git over outer bare' '
|
|
|
|
reset &&
|
|
|
|
make_tree foo &&
|
|
|
|
make_bare foo.git &&
|
|
|
|
mv foo/.git foo.git &&
|
|
|
|
get foo.git &&
|
|
|
|
check foo
|
|
|
|
'
|
|
|
|
|
|
|
|
test_done
|