Skip to content

Commit 726f89c

Browse files
committed
Merge branch 'nd/worktree-remove-with-uninitialized-submodules'
"git worktree remove" and "git worktree move" refused to work when there is a submodule involved. This has been loosened to ignore uninitialized submodules. * nd/worktree-remove-with-uninitialized-submodules: worktree: allow to (re)move worktrees with uninitialized submodules
2 parents bb20dbb + 00a6d4d commit 726f89c

File tree

2 files changed

+60
-6
lines changed

2 files changed

+60
-6
lines changed

builtin/worktree.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "refs.h"
1010
#include "run-command.h"
1111
#include "sigchain.h"
12+
#include "submodule.h"
1213
#include "refs.h"
1314
#include "utf8.h"
1415
#include "worktree.h"
@@ -724,20 +725,36 @@ static int unlock_worktree(int ac, const char **av, const char *prefix)
724725
static void validate_no_submodules(const struct worktree *wt)
725726
{
726727
struct index_state istate = { NULL };
728+
struct strbuf path = STRBUF_INIT;
727729
int i, found_submodules = 0;
728730

729-
if (read_index_from(&istate, worktree_git_path(wt, "index"),
730-
get_worktree_git_dir(wt)) > 0) {
731+
if (is_directory(worktree_git_path(wt, "modules"))) {
732+
/*
733+
* There could be false positives, e.g. the "modules"
734+
* directory exists but is empty. But it's a rare case and
735+
* this simpler check is probably good enough for now.
736+
*/
737+
found_submodules = 1;
738+
} else if (read_index_from(&istate, worktree_git_path(wt, "index"),
739+
get_worktree_git_dir(wt)) > 0) {
731740
for (i = 0; i < istate.cache_nr; i++) {
732741
struct cache_entry *ce = istate.cache[i];
742+
int err;
733743

734-
if (S_ISGITLINK(ce->ce_mode)) {
735-
found_submodules = 1;
736-
break;
737-
}
744+
if (!S_ISGITLINK(ce->ce_mode))
745+
continue;
746+
747+
strbuf_reset(&path);
748+
strbuf_addf(&path, "%s/%s", wt->path, ce->name);
749+
if (!is_submodule_populated_gently(path.buf, &err))
750+
continue;
751+
752+
found_submodules = 1;
753+
break;
738754
}
739755
}
740756
discard_index(&istate);
757+
strbuf_release(&path);
741758

742759
if (found_submodules)
743760
die(_("working trees containing submodules cannot be moved or removed"));

t/t2028-worktree-move.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,26 @@ test_expect_success 'move locked worktree (force)' '
112112
git worktree move --force --force flump ploof
113113
'
114114

115+
test_expect_success 'move a repo with uninitialized submodule' '
116+
git init withsub &&
117+
(
118+
cd withsub &&
119+
test_commit initial &&
120+
git submodule add "$PWD"/.git sub &&
121+
git commit -m withsub &&
122+
git worktree add second HEAD &&
123+
git worktree move second third
124+
)
125+
'
126+
127+
test_expect_success 'not move a repo with initialized submodule' '
128+
(
129+
cd withsub &&
130+
git -C third submodule update &&
131+
test_must_fail git worktree move third forth
132+
)
133+
'
134+
115135
test_expect_success 'remove main worktree' '
116136
test_must_fail git worktree remove .
117137
'
@@ -185,4 +205,21 @@ test_expect_success 'remove cleans up .git/worktrees when empty' '
185205
)
186206
'
187207

208+
test_expect_success 'remove a repo with uninitialized submodule' '
209+
(
210+
cd withsub &&
211+
git worktree add to-remove HEAD &&
212+
git worktree remove to-remove
213+
)
214+
'
215+
216+
test_expect_success 'not remove a repo with initialized submodule' '
217+
(
218+
cd withsub &&
219+
git worktree add to-remove HEAD &&
220+
git -C to-remove submodule update &&
221+
test_must_fail git worktree remove to-remove
222+
)
223+
'
224+
188225
test_done

0 commit comments

Comments
 (0)