connect.c: handle errors from split_cmdline
[gitweb.git] / dir.c
diff --git a/dir.c b/dir.c
index 9ae454ddec376461a429752b61ea8c34902d4ad9..65c3e681b8e04aa47b6cf41faca0822ead59fb6a 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -174,17 +174,21 @@ char *common_prefix(const struct pathspec *pathspec)
 
 int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)
 {
-       size_t len;
+       char *prefix;
+       size_t prefix_len;
 
        /*
         * Calculate common prefix for the pathspec, and
         * use that to optimize the directory walk
         */
-       len = common_prefix_len(pathspec);
+       prefix = common_prefix(pathspec);
+       prefix_len = prefix ? strlen(prefix) : 0;
 
        /* Read the directory and prune it */
-       read_directory(dir, pathspec->nr ? pathspec->_raw[0] : "", len, pathspec);
-       return len;
+       read_directory(dir, prefix, prefix_len, pathspec);
+
+       free(prefix);
+       return prefix_len;
 }
 
 int within_depth(const char *name, int namelen,
@@ -2721,3 +2725,40 @@ void untracked_cache_add_to_index(struct index_state *istate,
 {
        untracked_cache_invalidate_path(istate, path);
 }
+
+/* Update gitfile and core.worktree setting to connect work tree and git dir */
+void connect_work_tree_and_git_dir(const char *work_tree_, const char *git_dir_)
+{
+       struct strbuf file_name = STRBUF_INIT;
+       struct strbuf rel_path = STRBUF_INIT;
+       char *git_dir = real_pathdup(git_dir_);
+       char *work_tree = real_pathdup(work_tree_);
+
+       /* Update gitfile */
+       strbuf_addf(&file_name, "%s/.git", work_tree);
+       write_file(file_name.buf, "gitdir: %s",
+                  relative_path(git_dir, work_tree, &rel_path));
+
+       /* Update core.worktree setting */
+       strbuf_reset(&file_name);
+       strbuf_addf(&file_name, "%s/config", git_dir);
+       git_config_set_in_file(file_name.buf, "core.worktree",
+                              relative_path(work_tree, git_dir, &rel_path));
+
+       strbuf_release(&file_name);
+       strbuf_release(&rel_path);
+       free(work_tree);
+       free(git_dir);
+}
+
+/*
+ * Migrate the git directory of the given path from old_git_dir to new_git_dir.
+ */
+void relocate_gitdir(const char *path, const char *old_git_dir, const char *new_git_dir)
+{
+       if (rename(old_git_dir, new_git_dir) < 0)
+               die_errno(_("could not migrate git directory from '%s' to '%s'"),
+                       old_git_dir, new_git_dir);
+
+       connect_work_tree_and_git_dir(path, new_git_dir);
+}