Skip to content

Commit ee6763a

Browse files
pcloudsgitster
authored andcommitted
worktree remove: allow it when $GIT_WORK_TREE is already gone
"git worktree remove" basically consists of two things - delete $GIT_WORK_TREE - delete $GIT_DIR (which is $SUPER_GIT_DIR/worktrees/something) If $GIT_WORK_TREE is already gone for some reason, we should be able to finish the job by deleting $GIT_DIR. Two notes: - $GIT_WORK_TREE _can_ be missing if the worktree is locked. In that case we must not delete $GIT_DIR because the real $GIT_WORK_TREE may be in a usb stick somewhere. This is already handled because we check for lock first. - validate_worktree() is still called because it may do more checks in future (and it already does something else, like checking main worktree, but that's irrelevant in this case) Noticed-by: Kaartic Sivaraam <[email protected]> Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cc73385 commit ee6763a

File tree

4 files changed

+36
-7
lines changed

4 files changed

+36
-7
lines changed

builtin/worktree.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ static int move_worktree(int ac, const char **av, const char *prefix)
674674
reason);
675675
die(_("cannot move a locked working tree"));
676676
}
677-
if (validate_worktree(wt, &errmsg))
677+
if (validate_worktree(wt, &errmsg, 0))
678678
die(_("validation failed, cannot move working tree: %s"),
679679
errmsg.buf);
680680
strbuf_release(&errmsg);
@@ -799,15 +799,17 @@ static int remove_worktree(int ac, const char **av, const char *prefix)
799799
reason);
800800
die(_("cannot remove a locked working tree"));
801801
}
802-
if (validate_worktree(wt, &errmsg))
802+
if (validate_worktree(wt, &errmsg, WT_VALIDATE_WORKTREE_MISSING_OK))
803803
die(_("validation failed, cannot remove working tree: %s"),
804804
errmsg.buf);
805805
strbuf_release(&errmsg);
806806

807-
if (!force)
808-
check_clean_worktree(wt, av[0]);
807+
if (file_exists(wt->path)) {
808+
if (!force)
809+
check_clean_worktree(wt, av[0]);
809810

810-
ret |= delete_git_work_tree(wt);
811+
ret |= delete_git_work_tree(wt);
812+
}
811813
/*
812814
* continue on even if ret is non-zero, there's no going back
813815
* from here.

t/t2028-worktree-move.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,21 @@ test_expect_success 'force remove worktree with untracked file' '
126126
test_path_is_missing destination
127127
'
128128

129+
test_expect_success 'remove missing worktree' '
130+
git worktree add to-be-gone &&
131+
test -d .git/worktrees/to-be-gone &&
132+
mv to-be-gone gone &&
133+
git worktree remove to-be-gone &&
134+
test_path_is_missing .git/worktrees/to-be-gone
135+
'
136+
137+
test_expect_success 'NOT remove missing-but-locked worktree' '
138+
git worktree add gone-but-locked &&
139+
git worktree lock gone-but-locked &&
140+
test -d .git/worktrees/gone-but-locked &&
141+
mv gone-but-locked really-gone-now &&
142+
test_must_fail git worktree remove gone-but-locked &&
143+
test_path_is_dir .git/worktrees/gone-but-locked
144+
'
145+
129146
test_done

worktree.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ static void strbuf_addf_gently(struct strbuf *buf, const char *fmt, ...)
267267
va_end(params);
268268
}
269269

270-
int validate_worktree(const struct worktree *wt, struct strbuf *errmsg)
270+
int validate_worktree(const struct worktree *wt, struct strbuf *errmsg,
271+
unsigned flags)
271272
{
272273
struct strbuf wt_path = STRBUF_INIT;
273274
char *path = NULL;
@@ -303,6 +304,12 @@ int validate_worktree(const struct worktree *wt, struct strbuf *errmsg)
303304
goto done;
304305
}
305306

307+
if (flags & WT_VALIDATE_WORKTREE_MISSING_OK &&
308+
!file_exists(wt->path)) {
309+
ret = 0;
310+
goto done;
311+
}
312+
306313
if (!file_exists(wt_path.buf)) {
307314
strbuf_addf_gently(errmsg, _("'%s' does not exist"), wt_path.buf);
308315
goto done;

worktree.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,15 @@ extern int is_main_worktree(const struct worktree *wt);
6161
*/
6262
extern const char *is_worktree_locked(struct worktree *wt);
6363

64+
#define WT_VALIDATE_WORKTREE_MISSING_OK (1 << 0)
65+
6466
/*
6567
* Return zero if the worktree is in good condition. Error message is
6668
* returned if "errmsg" is not NULL.
6769
*/
6870
extern int validate_worktree(const struct worktree *wt,
69-
struct strbuf *errmsg);
71+
struct strbuf *errmsg,
72+
unsigned flags);
7073

7174
/*
7275
* Update worktrees/xxx/gitdir with the new path.

0 commit comments

Comments
 (0)