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>
maint
parent
aeb582a983
commit
105df73e71
|
@ -570,4 +570,16 @@ test_expect_success '"add" an existing locked but missing worktree' '
|
||||||
git worktree add --force --force --detach gnoo
|
git worktree add --force --force --detach gnoo
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success '"add" should not fail because of another bad worktree' '
|
||||||
|
git init add-fail &&
|
||||||
|
(
|
||||||
|
cd add-fail &&
|
||||||
|
test_commit first &&
|
||||||
|
mkdir sub &&
|
||||||
|
git worktree add sub/to-be-deleted &&
|
||||||
|
rm -rf sub &&
|
||||||
|
git worktree add second
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
|
@ -222,9 +222,12 @@ struct worktree *find_worktree(struct worktree **list,
|
||||||
free(to_free);
|
free(to_free);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (; *list; list++)
|
for (; *list; list++) {
|
||||||
if (!fspathcmp(path, real_path((*list)->path)))
|
const char *wt_path = real_path_if_valid((*list)->path);
|
||||||
|
|
||||||
|
if (wt_path && !fspathcmp(path, wt_path))
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
free(path);
|
free(path);
|
||||||
free(to_free);
|
free(to_free);
|
||||||
return *list;
|
return *list;
|
||||||
|
|
Loading…
Reference in New Issue