Merge branch 'jk/git-dir-lookup' into maint

* jk/git-dir-lookup:
  standardize and improve lookup rules for external local repos
This commit is contained in:
Junio C Hamano 2012-02-21 15:13:16 -08:00
Родитель a67c235448 b3256eb8b3
Коммит 0cfba96121
5 изменённых файлов: 109 добавлений и 5 удалений

Просмотреть файл

@ -105,7 +105,7 @@ static const char *argv_submodule[] = {
static char *get_repo_path(const char *repo, int *is_bundle) static char *get_repo_path(const char *repo, int *is_bundle)
{ {
static char *suffix[] = { "/.git", ".git", "" }; static char *suffix[] = { "/.git", "", ".git/.git", ".git" };
static char *bundle_suffix[] = { ".bundle", "" }; static char *bundle_suffix[] = { ".bundle", "" };
struct stat st; struct stat st;
int i; int i;
@ -115,7 +115,7 @@ static char *get_repo_path(const char *repo, int *is_bundle)
path = mkpath("%s%s", repo, suffix[i]); path = mkpath("%s%s", repo, suffix[i]);
if (stat(path, &st)) if (stat(path, &st))
continue; continue;
if (S_ISDIR(st.st_mode)) { if (S_ISDIR(st.st_mode) && is_git_directory(path)) {
*is_bundle = 0; *is_bundle = 0;
return xstrdup(absolute_path(path)); return xstrdup(absolute_path(path));
} else if (S_ISREG(st.st_mode) && st.st_size > 8) { } else if (S_ISREG(st.st_mode) && st.st_size > 8) {

Просмотреть файл

@ -432,6 +432,7 @@ extern char *git_work_tree_cfg;
extern int is_inside_work_tree(void); extern int is_inside_work_tree(void);
extern int have_git_dir(void); extern int have_git_dir(void);
extern const char *get_git_dir(void); extern const char *get_git_dir(void);
extern int is_git_directory(const char *path);
extern char *get_object_directory(void); extern char *get_object_directory(void);
extern char *get_index_file(void); extern char *get_index_file(void);
extern char *get_graft_file(void); extern char *get_graft_file(void);

7
path.c
Просмотреть файл

@ -293,7 +293,7 @@ const char *enter_repo(const char *path, int strict)
if (!strict) { if (!strict) {
static const char *suffix[] = { static const char *suffix[] = {
".git/.git", "/.git", ".git", "", NULL, "/.git", "", ".git/.git", ".git", NULL,
}; };
const char *gitfile; const char *gitfile;
int len = strlen(path); int len = strlen(path);
@ -324,8 +324,11 @@ const char *enter_repo(const char *path, int strict)
return NULL; return NULL;
len = strlen(used_path); len = strlen(used_path);
for (i = 0; suffix[i]; i++) { for (i = 0; suffix[i]; i++) {
struct stat st;
strcpy(used_path + len, suffix[i]); strcpy(used_path + len, suffix[i]);
if (!access(used_path, F_OK)) { if (!stat(used_path, &st) &&
(S_ISREG(st.st_mode) ||
(S_ISDIR(st.st_mode) && is_git_directory(used_path)))) {
strcat(validated_path, suffix[i]); strcat(validated_path, suffix[i]);
break; break;
} }

Просмотреть файл

@ -247,7 +247,7 @@ const char **get_pathspec(const char *prefix, const char **pathspec)
* a proper "ref:", or a regular file HEAD that has a properly * a proper "ref:", or a regular file HEAD that has a properly
* formatted sha1 object name. * formatted sha1 object name.
*/ */
static int is_git_directory(const char *suspect) int is_git_directory(const char *suspect)
{ {
char path[PATH_MAX]; char path[PATH_MAX];
size_t len = strlen(suspect); size_t len = strlen(suspect);

100
t/t5900-repo-selection.sh Executable file
Просмотреть файл

@ -0,0 +1,100 @@
#!/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" &&
tree=`git hash-object -w -t tree /dev/null` &&
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