This configuration variable comes into effect when 'git clone' is
invoked in an existing git repository.  Instead of cloning the
repository as-is, it relocates the gitdir of the repository to the
path specified by this variable.  Arguably, it does the right thing
when working with submodules.

Signed-off-by: Ramkumar Ramachandra <artag...@gmail.com>
---
 builtin/clone.c | 29 +++++++++++++++++++++++++++++
 environment.c   | 11 -----------
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/builtin/clone.c b/builtin/clone.c
index e0aaf13..1b798e6 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -43,6 +43,7 @@ static char *option_template, *option_depth;
 static char *option_origin = NULL;
 static char *option_branch = NULL;
 static const char *real_git_dir;
+static const char *submodule_gitdir;
 static char *option_upload_pack = "git-upload-pack";
 static int option_verbosity;
 static int option_progress = -1;
@@ -658,11 +659,22 @@ static void write_refspec_config(const char* 
src_ref_prefix,
        strbuf_release(&value);
 }
 
+static int git_clone_config(const char *var, const char *value, void *cb)
+{
+       if (!strcmp(var, "clone.submodulegitdir")) {
+               git_config_string(&submodule_gitdir, var, value);
+               return 0;
+       }
+       return git_default_config(var, value, cb);
+}
+
 int cmd_clone(int argc, const char **argv, const char *prefix)
 {
        int is_bundle = 0, is_local;
        struct stat buf;
        const char *repo_name, *repo, *work_tree, *git_dir;
+       char dest_git_dir[PATH_MAX];
+       char cwd[PATH_MAX];
        char *path, *dir;
        int dest_exists;
        const struct ref *refs, *remote_head;
@@ -676,6 +688,7 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
        const char *src_ref_prefix = "refs/heads/";
        struct remote *remote;
        int err = 0, complete_refs_before_fetch = 1;
+       int nongit = 1;
 
        struct refspec *refspec;
        const char *fetch_pattern;
@@ -683,6 +696,14 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
        junk_pid = getpid();
 
        packet_trace_identity("clone");
+
+       /* setup_git_directory_gently without changing directories */
+       getcwd(cwd, sizeof(cwd) - 1);
+       setup_git_directory_gently(&nongit);
+       chdir(cwd);
+
+       git_config(git_clone_config, NULL);
+
        argc = parse_options(argc, argv, prefix, builtin_clone_options,
                             builtin_clone_usage, 0);
 
@@ -736,6 +757,14 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
                die(_("destination path '%s' already exists and is not "
                        "an empty directory."), dir);
 
+       if (!nongit && submodule_gitdir) {
+               sprintf(dest_git_dir, "%s/%s.git", real_path(submodule_gitdir), 
dir);
+               if (!stat(dest_git_dir, &buf) && !is_empty_dir(dest_git_dir))
+                       die(_("destination path '%s' already exists and is not "
+                                       "an empty directory."), dest_git_dir);
+               real_git_dir = dest_git_dir;
+       }
+
        strbuf_addf(&reflog_msg, "clone: from %s", repo);
 
        if (option_bare)
diff --git a/environment.c b/environment.c
index e2e75c1..9dce4c7 100644
--- a/environment.c
+++ b/environment.c
@@ -182,8 +182,6 @@ const char *strip_namespace(const char *namespaced_ref)
        return namespaced_ref + namespace_len;
 }
 
-static int git_work_tree_initialized;
-
 /*
  * Note.  This works only before you used a work tree.  This was added
  * primarily to support git-clone to work in a new repository it just
@@ -191,15 +189,6 @@ static int git_work_tree_initialized;
  */
 void set_git_work_tree(const char *new_work_tree)
 {
-       if (git_work_tree_initialized) {
-               new_work_tree = real_path(new_work_tree);
-               if (strcmp(new_work_tree, work_tree))
-                       die("internal error: work tree has already been set\n"
-                           "Current worktree: %s\nNew worktree: %s",
-                           work_tree, new_work_tree);
-               return;
-       }
-       git_work_tree_initialized = 1;
        work_tree = xstrdup(real_path(new_work_tree));
 }
 
-- 
1.8.2.380.g0d4e79b

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to