Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> writes: > Uninitialized submodules have nothing valueable for us to be worried > about. They are just SHA-1. Let "worktree remove" and "worktree move" > continue in this case so that people can still use multiple worktrees > on repos with optional submodules that are never populated, like > sha1collisiondetection in git.git when checked out by doc-diff script. > > Note that for "worktree remove", it is possible that a user > initializes a submodule (*), makes some commits (but not push), then > deinitializes it. At that point, the submodule is unpopulated, but the > precious new commits are still in > > $GIT_COMMON_DIR/worktrees/<worktree>/modules/<submodule> > > directory and we should not allow removing the worktree or we lose > those commits forever. The new directory check is added to prevent > this. > > (*) yes they are screwed anyway by doing this since "git submodule" > would add submodule.* in $GIT_COMMON_DIR/config, which is shared > across multiple worktrees. But it does not mean we let them be > screwed even more. > > Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> > --- > Fixed Eric's comment. I was a bit annoyed by the duplicate die() too > but didn't think of adding "else" in front of "if (read_index" > > builtin/worktree.c | 29 +++++++++++++++++++++++------ > 1 file changed, 23 insertions(+), 6 deletions(-) Is this a fair description for this 1-patch topic? "git worktree remove" and "git worktree move" failed to work when there is an uninitialized submodule, which has been fixed. If so, can we have a test case to cover this fix? Thanks. > diff --git a/builtin/worktree.c b/builtin/worktree.c > index 5e84026177..3f9907fcc9 100644 > --- a/builtin/worktree.c > +++ b/builtin/worktree.c > @@ -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" > @@ -724,20 +725,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"));