Subject: Re: workdirs: cannot clone a local workdir directory

From: Duy Nguyen <[email-masked]>
Date: Wed, 15 Jul 2015 20:25:52 +0700

On Wed, Jul 15, 2015 at 11:40:18AM +0200, Bjørnar Snoksrud wrote:
> I reported this before, but now I have a nice topic to hang it on -
> 
> I have re-reproduced the bug using a build from master as of today,
> using the new worktree commands.

Something like the following patch should work if you need it now.

Because this may conflict (in the test cases) with Eric's series to
move "git checkout --to" to "git worktree add", and because the next
release is already delayed to let "git worktree add" in, I think we
could keep this patch out of tree for now. I will split it up, add
tests and resubmit once the release is out. Please remind me if you
see nothing from me for too long.

Note to self, "git clone --reference" remains broken.

-- 8< --
diff --git a/builtin/clone.c b/builtin/clone.c
index 00535d0..0e594f1 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -373,8 +373,10 @@ static void clone_local(const char *src_repo, const char *dest_repo)
 	} else {
 		struct strbuf src = STRBUF_INIT;
 		struct strbuf dest = STRBUF_INIT;
-		strbuf_addf(&src, "%s/objects", src_repo);
-		strbuf_addf(&dest, "%s/objects", dest_repo);
+		get_common_dir(&src, src_repo);
+		get_common_dir(&dest, dest_repo);
+		strbuf_addstr(&src, "/objects");
+		strbuf_addf(&dest, "/objects");
 		copy_or_link_directory(&src, &dest, src_repo, src.len);
 		strbuf_release(&src);
 		strbuf_release(&dest);
diff --git a/path.c b/path.c
index 10f4cbf..7f7b56f 100644
--- a/path.c
+++ b/path.c
@@ -416,18 +416,22 @@ const char *enter_repo(const char *path, int strict)
 		}
 		if (!suffix[i])
 			return NULL;
-		gitfile = read_gitfile(used_path) ;
+		gitfile = read_gitfile(used_path);
 		if (gitfile)
 			strcpy(used_path, gitfile);
 		if (chdir(used_path))
 			return NULL;
 		path = validated_path;
 	}
-	else if (chdir(path))
-		return NULL;
+	else {
+		const char *gitfile = read_gitfile(used_path);
+		if (gitfile)
+			path = gitfile;
+		if (chdir(path))
+			return NULL;
+	}
 
-	if (access("objects", X_OK) == 0 && access("refs", X_OK) == 0 &&
-	    validate_headref("HEAD") == 0) {
+	if (is_git_directory(".")) {
 		set_git_dir(".");
 		check_repository_format();
 		return path;
-- 8< --