pack-objects: default to writing bitmap hash-cache
[gitweb.git] / builtin / worktree.c
index c4abbde2b87e00944eb86fe2393daf477da976b6..6cc094a453806308442d054a7d1c073ecf18b87b 100644 (file)
@@ -9,6 +9,7 @@
 #include "refs.h"
 #include "run-command.h"
 #include "sigchain.h"
+#include "submodule.h"
 #include "refs.h"
 #include "utf8.h"
 #include "worktree.h"
@@ -245,7 +246,7 @@ static void validate_worktree_add(const char *path, const struct add_opts *opts)
        if (!wt)
                goto done;
 
-       locked = !!is_worktree_locked(wt);
+       locked = !!worktree_lock_reason(wt);
        if ((!locked && opts->force) || (locked && opts->force > 1)) {
                if (delete_git_dir(wt->id))
                    die(_("unable to re-add worktree '%s'"), path);
@@ -401,6 +402,7 @@ static int add_worktree(const char *path, const char *refname,
                        cp.dir = path;
                        cp.env = env;
                        cp.argv = NULL;
+                       cp.trace2_hook_name = "post-checkout";
                        argv_array_pushl(&cp.args, absolute_path(hook),
                                         oid_to_hex(&null_oid),
                                         oid_to_hex(&commit->object.oid),
@@ -682,7 +684,7 @@ static int lock_worktree(int ac, const char **av, const char *prefix)
        if (is_main_worktree(wt))
                die(_("The main working tree cannot be locked or unlocked"));
 
-       old_reason = is_worktree_locked(wt);
+       old_reason = worktree_lock_reason(wt);
        if (old_reason) {
                if (*old_reason)
                        die(_("'%s' is already locked, reason: %s"),
@@ -714,7 +716,7 @@ static int unlock_worktree(int ac, const char **av, const char *prefix)
                die(_("'%s' is not a working tree"), av[0]);
        if (is_main_worktree(wt))
                die(_("The main working tree cannot be locked or unlocked"));
-       if (!is_worktree_locked(wt))
+       if (!worktree_lock_reason(wt))
                die(_("'%s' is not locked"), av[0]);
        ret = unlink_or_warn(git_common_path("worktrees/%s/locked", wt->id));
        free_worktrees(worktrees);
@@ -724,20 +726,36 @@ static int unlock_worktree(int ac, const char **av, const char *prefix)
 static void validate_no_submodules(const struct worktree *wt)
 {
        struct index_state istate = { NULL };
+       struct strbuf path = STRBUF_INIT;
        int i, found_submodules = 0;
 
-       if (read_index_from(&istate, worktree_git_path(wt, "index"),
-                           get_worktree_git_dir(wt)) > 0) {
+       if (is_directory(worktree_git_path(wt, "modules"))) {
+               /*
+                * There could be false positives, e.g. the "modules"
+                * directory exists but is empty. But it's a rare case and
+                * this simpler check is probably good enough for now.
+                */
+               found_submodules = 1;
+       } else if (read_index_from(&istate, worktree_git_path(wt, "index"),
+                                  get_worktree_git_dir(wt)) > 0) {
                for (i = 0; i < istate.cache_nr; i++) {
                        struct cache_entry *ce = istate.cache[i];
+                       int err;
 
-                       if (S_ISGITLINK(ce->ce_mode)) {
-                               found_submodules = 1;
-                               break;
-                       }
+                       if (!S_ISGITLINK(ce->ce_mode))
+                               continue;
+
+                       strbuf_reset(&path);
+                       strbuf_addf(&path, "%s/%s", wt->path, ce->name);
+                       if (!is_submodule_populated_gently(path.buf, &err))
+                               continue;
+
+                       found_submodules = 1;
+                       break;
                }
        }
        discard_index(&istate);
+       strbuf_release(&path);
 
        if (found_submodules)
                die(_("working trees containing submodules cannot be moved or removed"));
@@ -787,7 +805,7 @@ static int move_worktree(int ac, const char **av, const char *prefix)
        validate_no_submodules(wt);
 
        if (force < 2)
-               reason = is_worktree_locked(wt);
+               reason = worktree_lock_reason(wt);
        if (reason) {
                if (*reason)
                        die(_("cannot move a locked working tree, lock reason: %s\nuse 'move -f -f' to override or unlock first"),
@@ -900,7 +918,7 @@ static int remove_worktree(int ac, const char **av, const char *prefix)
        if (is_main_worktree(wt))
                die(_("'%s' is a main working tree"), av[0]);
        if (force < 2)
-               reason = is_worktree_locked(wt);
+               reason = worktree_lock_reason(wt);
        if (reason) {
                if (*reason)
                        die(_("cannot remove a locked working tree, lock reason: %s\nuse 'remove -f -f' to override or unlock first"),