refs: move submodule code out of files-backend.c
[gitweb.git] / worktree.c
index eb6121263b0d56b6b7ea7c5024e9ceb68256c1c5..fa7bc67a50a6d52116b0ca994b473668998f1c3f 100644 (file)
@@ -145,7 +145,7 @@ static struct worktree *get_linked_worktree(const char *id)
 
 static void mark_current_worktree(struct worktree **worktrees)
 {
-       char *git_dir = xstrdup(absolute_path(get_git_dir()));
+       char *git_dir = absolute_pathdup(get_git_dir());
        int i;
 
        for (i = 0; worktrees[i]; i++) {
@@ -175,7 +175,7 @@ struct worktree **get_worktrees(unsigned flags)
        struct dirent *d;
        int counter = 0, alloc = 2;
 
-       list = xmalloc(alloc * sizeof(struct worktree *));
+       ALLOC_ARRAY(list, alloc);
 
        list[counter++] = get_main_worktree();
 
@@ -255,7 +255,7 @@ struct worktree *find_worktree(struct worktree **list,
                return wt;
 
        arg = prefix_filename(prefix, strlen(prefix), arg);
-       path = xstrdup(real_path(arg));
+       path = real_pathdup(arg, 1);
        for (; *list; list++)
                if (!fspathcmp(path, real_path((*list)->path)))
                        break;
@@ -380,3 +380,53 @@ const struct worktree *find_shared_symref(const char *symref,
 
        return existing;
 }
+
+int submodule_uses_worktrees(const char *path)
+{
+       char *submodule_gitdir;
+       struct strbuf sb = STRBUF_INIT;
+       DIR *dir;
+       struct dirent *d;
+       int ret = 0;
+       struct repository_format format;
+
+       submodule_gitdir = git_pathdup_submodule(path, "%s", "");
+       if (!submodule_gitdir)
+               return 0;
+
+       /* The env would be set for the superproject. */
+       get_common_dir_noenv(&sb, submodule_gitdir);
+
+       /*
+        * The check below is only known to be good for repository format
+        * version 0 at the time of writing this code.
+        */
+       strbuf_addstr(&sb, "/config");
+       read_repository_format(&format, sb.buf);
+       if (format.version != 0) {
+               strbuf_release(&sb);
+               return 1;
+       }
+
+       /* Replace config by worktrees. */
+       strbuf_setlen(&sb, sb.len - strlen("config"));
+       strbuf_addstr(&sb, "worktrees");
+
+       /* See if there is any file inside the worktrees directory. */
+       dir = opendir(sb.buf);
+       strbuf_release(&sb);
+       free(submodule_gitdir);
+
+       if (!dir)
+               return 0;
+
+       while ((d = readdir(dir)) != NULL) {
+               if (is_dot_or_dotdot(d->d_name))
+                       continue;
+
+               ret = 1;
+               break;
+       }
+       closedir(dir);
+       return ret;
+}