git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2/8] worktree: prune corrupted worktree even if locked

From
Eric Sunshine <sunshine@sunshineco.com>
Date
Jun 8, 2020, 06:23 UTC
Message-ID
<20200608062356.40264-3-sunshine@sunshineco.com>
In-Reply-To
<20200608062356.40264-1-sunshine@sunshineco.com>

The .git/worktrees/<id>/locked file created by "git worktree lock" is intended to prevent a missing worktree -- which might reside on a removable device or network share -- from being pruned. It is not meant to prevent a corrupt worktree from being pruned, yet it short-circuits almost all "git worktree prune" corruption checks. This can make it impossible[1] to prune a worktree which becomes corrupt after the lock is placed since "git worktree prune" won't prune it, and it may not even be possible to unlock it with "git worktree unlock", depending upon the nature of the corruption.

Therefore, delay the check for .git/worktrees/<id>/locked until after all forms of corruption have been checked so that it behaves as originally intended (to wit: preventing pruning of a missing worktree only).

[1]: Impossible, that is, without manually mucking around with
     .git/worktrees/<id>/ administrative files.
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---
 builtin/worktree.c        |  4 ++--
 t/t2401-worktree-prune.sh | 14 ++++++++++++--
 2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 9b15f19fc5..f7351413af 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -79,8 +79,6 @@ static int prune_worktree(const char *id, struct strbuf *reason)
 		strbuf_addstr(reason, _("not a valid directory"));
 		return 1;
 	}
-	if (file_exists(git_path("worktrees/%s/locked", id)))
-		return 0;
 	if (stat(git_path("worktrees/%s/gitdir", id), &st)) {
 		strbuf_addstr(reason, _("gitdir file does not exist"));
 		return 1;
@@ -121,6 +119,8 @@ static int prune_worktree(const char *id, struct strbuf *reason)
 	path[len] = '\0';
 	if (!file_exists(path)) {
 		free(path);
+		if (file_exists(git_path("worktrees/%s/locked", id)))
+			return 0;
 		if (stat(git_path("worktrees/%s/index", id), &st) ||
 		    st.st_mtime <= expire) {
 			strbuf_addstr(reason, _("gitdir file points to non-existent location"));
diff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh
index b7d6d5d45a..9be8e97d66 100755
--- a/t/t2401-worktree-prune.sh
+++ b/t/t2401-worktree-prune.sh
@@ -69,13 +69,23 @@ test_expect_success 'prune directories with gitdir pointing to nowhere' '
 '
 
 test_expect_success 'not prune locked checkout' '
-	test_when_finished rm -r .git/worktrees &&
-	mkdir -p .git/worktrees/ghi &&
+	test_when_finished rm -fr .git/worktrees ghi &&
+	git worktree add ghi &&
 	: >.git/worktrees/ghi/locked &&
+	rm -r ghi &&
 	git worktree prune &&
 	test -d .git/worktrees/ghi
 '
 
+test_expect_success 'prune corrupt despite lock' '
+	test_when_finished rm -fr .git/worktrees ghi &&
+	mkdir -p .git/worktrees/ghi &&
+	: >.git/worktrees/ghi/gitdir &&
+	: >.git/worktrees/ghi/locked &&
+	git worktree prune &&
+	! test -d .git/worktrees/ghi
+'
+
 test_expect_success 'not prune recent checkouts' '
 	test_when_finished rm -r .git/worktrees &&
 	git worktree add jlm HEAD &&
-- 
2.27.0.290.gba653c62da
Previous: Junio C HamanoNext: Junio C Hamano
Message 7 of 20 in “worktree: tighten duplicate path detection”
  1. 0/8 worktree: tighten duplicate path detectionEric Sunshine, Jun 8, 2020
  2. 1/8 worktree: factor out repeated string literalEric Sunshine, Jun 8, 2020
  3. Shourya ShuklaJun 8, 2020
  4. Eric SunshineJun 8, 2020
  5. 3/8 worktree: give "should be pruned?" function more meaningful nameEric Sunshine, Jun 8, 2020
  6. Junio C HamanoJun 8, 2020
  7. 2/8 worktree: prune corrupted worktree even if lockedEric Sunshine, Jun 8, 2020
  8. Junio C HamanoJun 8, 2020
  9. Eric SunshineJun 9, 2020
  10. 4/8 worktree: make high-level pruning re-usableEric Sunshine, Jun 8, 2020
  11. Junio C HamanoJun 8, 2020
  12. 6/8 worktree: prune linked worktree referencing main worktree pathEric Sunshine, Jun 8, 2020
  13. Junio C HamanoJun 8, 2020
  14. Eric SunshineJun 9, 2020
  15. 7/8 worktree: generalize candidate worktree path validationEric Sunshine, Jun 8, 2020
  16. Junio C HamanoJun 8, 2020
  17. 8/8 worktree: make "move" refuse to move atop missing registered worktreeEric Sunshine, Jun 8, 2020
  18. Eric SunshineJun 8, 2020
  19. Junio C HamanoJun 8, 2020
  20. 5/8 worktree: prune duplicate entries referencing same worktree pathEric Sunshine, Jun 8, 2020

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.