worktree add: be tolerant of corrupt worktrees

find_worktree() can die() unexpectedly because it uses real_path() instead of the gentler version. When it's used in 'git worktree add' [1] and there's a bad worktree, this die() could prevent people from adding new worktrees. The "bad" condition to trigger this is when a parent of the worktree's location is deleted. Then real_path() will complain. Use the other version so that bad worktrees won't affect 'worktree add'. The bad ones will eventually be pruned, we just have to tolerate them for a bit. [1] added in cb56f55c16 (worktree: disallow adding same path multiple times, 2018-08-28), or since v2.20.0. Though the real bug in find_worktree() is much older. Reported-by: Shaheed Haque <shaheedhaque@gmail.com> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed May 13, 2019 at 17:49 UTC 105df73e71a9eb901d7ca96f12ce3645729ae486
2 files changed +17 -2
t/t2025-worktree-add.sh
+12
@@ -570,4 +570,16 @@ test_expect_success '"add" an existing locked but missing worktree' '
570 git worktree add --force --force --detach gnoo
571 '
572
573 +test_expect_success '"add" should not fail because of another bad worktree' '
574 + git init add-fail &&
575 + (
576 + cd add-fail &&
577 + test_commit first &&
578 + mkdir sub &&
579 + git worktree add sub/to-be-deleted &&
580 + rm -rf sub &&
581 + git worktree add second
582 + )
583 +'
584 +
585 test_done
worktree.c
+5 -2
@@ -222,9 +222,12 @@ struct worktree *find_worktree(struct worktree **list,
222 free(to_free);
223 return NULL;
224 }
225 - for (; *list; list++)
226 - if (!fspathcmp(path, real_path((*list)->path)))
225 + for (; *list; list++) {
226 + const char *wt_path = real_path_if_valid((*list)->path);
227 +
228 + if (wt_path && !fspathcmp(path, wt_path))
229 break;
230 + }
231 free(path);
232 free(to_free);
233 return *list;