Skip to content

Commit 4349f59

Browse files
committed
Merge branch 'nd/clone-linked-checkout' into maint
It was not possible to use a repository-lookalike created by "git worktree add" as a local source of "git clone". * nd/clone-linked-checkout: clone: better error when --reference is a linked checkout clone: allow --local from a linked checkout enter_repo: allow .git files in strict mode enter_repo: avoid duplicating logic, use is_git_directory() instead t0002: add test for enter_repo(), non-strict mode path.c: delete an extra space
2 parents 53be145 + d78db84 commit 4349f59

File tree

4 files changed

+66
-8
lines changed

4 files changed

+66
-8
lines changed

builtin/clone.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,14 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)
294294
char *ref_git_git = mkpathdup("%s/.git", ref_git);
295295
free(ref_git);
296296
ref_git = ref_git_git;
297-
} else if (!is_directory(mkpath("%s/objects", ref_git)))
297+
} else if (!is_directory(mkpath("%s/objects", ref_git))) {
298+
struct strbuf sb = STRBUF_INIT;
299+
if (get_common_dir(&sb, ref_git))
300+
die(_("reference repository '%s' as a linked checkout is not supported yet."),
301+
item->string);
298302
die(_("reference repository '%s' is not a local repository."),
299303
item->string);
304+
}
300305

301306
if (!access(mkpath("%s/shallow", ref_git), F_OK))
302307
die(_("reference repository '%s' is shallow"), item->string);
@@ -424,8 +429,10 @@ static void clone_local(const char *src_repo, const char *dest_repo)
424429
} else {
425430
struct strbuf src = STRBUF_INIT;
426431
struct strbuf dest = STRBUF_INIT;
427-
strbuf_addf(&src, "%s/objects", src_repo);
428-
strbuf_addf(&dest, "%s/objects", dest_repo);
432+
get_common_dir(&src, src_repo);
433+
get_common_dir(&dest, dest_repo);
434+
strbuf_addstr(&src, "/objects");
435+
strbuf_addstr(&dest, "/objects");
429436
copy_or_link_directory(&src, &dest, src_repo, src.len);
430437
strbuf_release(&src);
431438
strbuf_release(&dest);

path.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -445,18 +445,22 @@ const char *enter_repo(const char *path, int strict)
445445
}
446446
if (!suffix[i])
447447
return NULL;
448-
gitfile = read_gitfile(used_path) ;
448+
gitfile = read_gitfile(used_path);
449449
if (gitfile)
450450
strcpy(used_path, gitfile);
451451
if (chdir(used_path))
452452
return NULL;
453453
path = validated_path;
454454
}
455-
else if (chdir(path))
456-
return NULL;
455+
else {
456+
const char *gitfile = read_gitfile(path);
457+
if (gitfile)
458+
path = gitfile;
459+
if (chdir(path))
460+
return NULL;
461+
}
457462

458-
if (access("objects", X_OK) == 0 && access("refs", X_OK) == 0 &&
459-
validate_headref("HEAD") == 0) {
463+
if (is_git_directory(".")) {
460464
set_git_dir(".");
461465
check_repository_format();
462466
return path;

t/t0002-gitfile.sh

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,46 @@ test_expect_success 'setup_git_dir twice in subdir' '
116116
)
117117
'
118118

119+
test_expect_success 'enter_repo non-strict mode' '
120+
test_create_repo enter_repo &&
121+
(
122+
cd enter_repo &&
123+
test_tick &&
124+
test_commit foo &&
125+
mv .git .realgit &&
126+
echo "gitdir: .realgit" >.git
127+
) &&
128+
git ls-remote enter_repo >actual &&
129+
cat >expected <<-\EOF &&
130+
946e985ab20de757ca5b872b16d64e92ff3803a9 HEAD
131+
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/heads/master
132+
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/tags/foo
133+
EOF
134+
test_cmp expected actual
135+
'
136+
137+
test_expect_success 'enter_repo linked checkout' '
138+
(
139+
cd enter_repo &&
140+
git worktree add ../foo refs/tags/foo
141+
) &&
142+
git ls-remote foo >actual &&
143+
cat >expected <<-\EOF &&
144+
946e985ab20de757ca5b872b16d64e92ff3803a9 HEAD
145+
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/heads/master
146+
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/tags/foo
147+
EOF
148+
test_cmp expected actual
149+
'
150+
151+
test_expect_success 'enter_repo strict mode' '
152+
git ls-remote --upload-pack="git upload-pack --strict" foo/.git >actual &&
153+
cat >expected <<-\EOF &&
154+
946e985ab20de757ca5b872b16d64e92ff3803a9 HEAD
155+
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/heads/master
156+
946e985ab20de757ca5b872b16d64e92ff3803a9 refs/tags/foo
157+
EOF
158+
test_cmp expected actual
159+
'
160+
119161
test_done

t/t2025-worktree-add.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,9 @@ test_expect_success '"add" -B/--detach mutually exclusive' '
193193
test_must_fail git worktree add -B poodle --detach bamboo master
194194
'
195195

196+
test_expect_success 'local clone from linked checkout' '
197+
git clone --local here here-clone &&
198+
( cd here-clone && git fsck )
199+
'
200+
196201
test_done

0 commit comments

Comments
 (0)