mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-11-06 13:00:59 -04:00
Fix crash when two worktrees have the same path
If a linked worktree's directory is deleted and another worktree is moved to the same path, `git worktree list` reports both worktrees with that path. lazygit then crashes at startup with a stack overflow, and the terminal is left in a broken state. To tell the paths in a group apart, getUniqueNamesFromPathsAux keeps looking at one more parent directory, but identical paths never come apart, so it recurses forever. A stack overflow is a fatal error rather than a panic. No deferred function runs, so the terminal is not restored either. Name identical paths like a single path instead of recursing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
29e8c79ff5
commit
ebee95b847
@@ -236,9 +236,16 @@ func getUniqueNamesFromPathsAux(paths []pathWithIndexT, depth int) []nameWithInd
|
||||
|
||||
result := []nameWithIndexT{}
|
||||
for _, group := range groups {
|
||||
if len(group) == 1 {
|
||||
path := group[0]
|
||||
result = append(result, nameWithIndexT{index: path.index, name: sliceAtDepth(path.path, depth)})
|
||||
// Identical paths can't be told apart at any depth, so they are named
|
||||
// like a single path. Git reports two worktrees with the same path when
|
||||
// a worktree directory was deleted and another worktree was moved to
|
||||
// its place.
|
||||
if lo.EveryBy(group, func(path pathWithIndexT) bool {
|
||||
return trimSlashes(path.path) == trimSlashes(group[0].path)
|
||||
}) {
|
||||
for _, path := range group {
|
||||
result = append(result, nameWithIndexT{index: path.index, name: sliceAtDepth(path.path, depth)})
|
||||
}
|
||||
} else {
|
||||
result = append(result, getUniqueNamesFromPathsAux(group, depth+1)...)
|
||||
}
|
||||
|
||||
@@ -353,6 +353,28 @@ func TestGetUniqueNamesFromPaths(t *testing.T) {
|
||||
"e/c/d",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: []string{
|
||||
"/a/b/c",
|
||||
"/a/b/c",
|
||||
},
|
||||
expected: []string{
|
||||
"c",
|
||||
"c",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: []string{
|
||||
"/a/b/c",
|
||||
"/a/b/c/",
|
||||
"/a/d/c",
|
||||
},
|
||||
expected: []string{
|
||||
"b/c",
|
||||
"b/c",
|
||||
"d/c",
|
||||
},
|
||||
},
|
||||
} {
|
||||
actual := getUniqueNamesFromPaths(scenario.input)
|
||||
assert.EqualValues(t, scenario.expected, actual)
|
||||
|
||||
Reference in New Issue
Block a user