diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 8537692f05..d08b8d8e4f 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -125,6 +125,9 @@ OPTIONS manually). This option overrides these safeguards. To add a missing but locked working tree path, specify `--force` twice. + +`move` refuses to move a locked working tree unless `--force` is specified +twice. ++ `remove` refuses to remove an unclean working tree unless `--force` is used. -b :: diff --git a/builtin/worktree.c b/builtin/worktree.c index 3eb2f89b0f..354a6c0eb5 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -740,13 +740,17 @@ static void validate_no_submodules(const struct worktree *wt) static int move_worktree(int ac, const char **av, const char *prefix) { + int force = 0; struct option options[] = { + OPT__FORCE(&force, + N_("force move even if worktree is dirty or locked"), + PARSE_OPT_NOCOMPLETE), OPT_END() }; struct worktree **worktrees, *wt; struct strbuf dst = STRBUF_INIT; struct strbuf errmsg = STRBUF_INIT; - const char *reason; + const char *reason = NULL; char *path; ac = parse_options(ac, av, prefix, options, worktree_usage, 0); @@ -777,12 +781,13 @@ static int move_worktree(int ac, const char **av, const char *prefix) validate_no_submodules(wt); - reason = is_worktree_locked(wt); + if (force < 2) + reason = is_worktree_locked(wt); if (reason) { if (*reason) - die(_("cannot move a locked working tree, lock reason: %s"), + die(_("cannot move a locked working tree, lock reason: %s\nuse 'move -f -f' to override or unlock first"), reason); - die(_("cannot move a locked working tree")); + die(_("cannot move a locked working tree;\nuse 'move -f -f' to override or unlock first")); } if (validate_worktree(wt, &errmsg, 0)) die(_("validation failed, cannot move working tree: %s"), diff --git a/t/t2028-worktree-move.sh b/t/t2028-worktree-move.sh index 60aba7c41a..9756ede8f1 100755 --- a/t/t2028-worktree-move.sh +++ b/t/t2028-worktree-move.sh @@ -98,6 +98,20 @@ test_expect_success 'move worktree to another dir' ' test_cmp expected2 actual2 ' +test_expect_success 'move locked worktree (force)' ' + test_when_finished " + git worktree unlock flump || : + git worktree remove flump || : + git worktree unlock ploof || : + git worktree remove ploof || : + " && + git worktree add --detach flump && + git worktree lock flump && + test_must_fail git worktree move flump ploof" && + test_must_fail git worktree move --force flump ploof" && + git worktree move --force --force flump ploof +' + test_expect_success 'remove main worktree' ' test_must_fail git worktree remove . '