Submodules contains .git files with relative paths. After a worktree move, these files need to be updated or they may point to nowhere. This is a bandage patch to make sure "worktree move" don't break people's worktrees by accident. When .git file update code is in place, this validate_no_submodules() could be removed. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- Documentation/git-worktree.txt | 2 +- builtin/worktree.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 5d115b855a..24bb69de50 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -83,7 +83,7 @@ with `--reason`. move:: Move a working tree to a new location. Note that the main working tree -cannot be moved. +or linked working trees containing submodules cannot be moved. prune:: diff --git a/builtin/worktree.c b/builtin/worktree.c index 89398e67e4..15980a0a49 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -606,6 +606,27 @@ static int unlock_worktree(int ac, const char **av, const char *prefix) return ret; } +static void validate_no_submodules(const struct worktree *wt) +{ + struct index_state istate = { NULL }; + int i, found_submodules = 0; + + if (read_index_from(&istate, worktree_git_path(wt, "index")) > 0) { + for (i = 0; i < istate.cache_nr; i++) { + struct cache_entry *ce = istate.cache[i]; + + if (S_ISGITLINK(ce->ce_mode)) { + found_submodules = 1; + break; + } + } + } + discard_index(&istate); + + if (found_submodules) + die(_("working trees containing submodules cannot be moved")); +} + static int move_worktree(int ac, const char **av, const char *prefix) { struct option options[] = { @@ -632,6 +653,8 @@ static int move_worktree(int ac, const char **av, const char *prefix) if (is_main_worktree(wt)) die(_("'%s' is a main working tree"), av[0]); + validate_no_submodules(wt); + if (is_directory(dst.buf)) { const char *sep = find_last_dir_sep(wt->path); -- 2.16.0.47.g3d9b0fac3a