Skip to content

Conversation

@stefanhaller
Copy link
Collaborator

Users have filed issues with crash reports that seem to indicate that the FileTreeViewModel gets swapped out (by a refresh) while a call to itemsSelected is in progress, iterating over the previous items. Guard against this by locking the mutex that we already have for this for the duration of the call.

I don't have a good way of testing whether the fix helps, because the crashes only occurred very infrequently. Let's just see if the crash reports stop coming in after we ship this.

Note also that this is only the minimal fix for the crashes that were reported. Theoretically, the same problem could happen for a key handler itself, but we never saw reports about that, so we don't bother doing anything about that yet.

Note also that long-term I envision a different solution to this class of problems (discussed in #2974), that's why I want to avoid locking mutexes more than necessary now.

Fixes #3646
Fixes #4154
Fixes #4301
Fixes #5070

@stefanhaller stefanhaller added the bug Something isn't working label Nov 27, 2025
@codacy-production
Copy link

codacy-production bot commented Nov 27, 2025

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
Report missing for d1d2bb21 100.00%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (d1d2bb2) Report Missing Report Missing Report Missing
Head commit (d274474) 59216 51506 86.98%

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#5074) 11 11 100.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Footnotes

  1. Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.

@stefanhaller stefanhaller mentioned this pull request Nov 27, 2025
Copy link
Contributor

@ChrisMcD1 ChrisMcD1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Band aid looks good to me!

I never got my fix to a happy place, it was going to be a big lift!

The big idea of my large change was instead of having a:

type IFileTreeViewModel interface {
	IFileTree
	types.IListCursor
}

that other people can mess around with and screw up our connection between our IFileTree and IListCursor, we would have a version that has locks around each path, so that it could only be viewed in a consistent state.

type IFileTreeViewModel interface {
	GetSelected() *FileNode
	GetSelectedItemId() string
	GetSelectedItems() ([]*FileNode, int, int)
	GetSelectedItemIds() ([]string, int, int)
	GetSelectedFile() *models.File
	GetSelectedPath() string
	RefreshTree()
	SetStatusFilter(filter FileTreeDisplayFilter)
	ToggleShowTree()
	CollapseAll()
	ExpandAll()
}

The LOC change was going to be tremendous I imagine, and I would want to do a similar thing to other combinations of List and View, which did not seem tenable

@stefanhaller
Copy link
Collaborator Author

The big idea of my large change was instead of having a:

As I tried to explain in #4301, this is not a direction I want to take. This only addresses the specific problem of the file tree, but we have the same (or similar) concurrency issues all over the place with other data (like other model stuff, and even views), and I'd rather have a more generic solution that addresses all of that at a more fundamental level.

Users have filed issues with crash reports that seem to indicate that the
FileTreeViewModel gets swapped out (by a refresh) while a call to itemsSelected
is in progress, iterating over the previous items. Guard against this by locking
the mutex that we already have for this for the duration of the call.

I don't have a good way of testing whether the fix helps, because the crashes
only occurred very infrequently. Let's just see if the crash reports stop coming
in after we ship this.

Note also that this is only the minimal fix for the crashes that were reported.
Theoretically, the same problem could happen for a key handler itself, but we
never saw reports about that, so we don't bother doing anything about that yet.

Note also that long-term I envision a different solution to this class of
problems (discussed in #2974),
that's why I want to avoid locking mutexes more than necessary now.
@stefanhaller stefanhaller force-pushed the work-around-crashes-in-FilesController branch from 8bdfe48 to d274474 Compare December 3, 2025 07:08
@stefanhaller stefanhaller merged commit 8396747 into master Dec 3, 2025
13 checks passed
@stefanhaller stefanhaller deleted the work-around-crashes-in-FilesController branch December 3, 2025 07:10
@ChrisMcD1
Copy link
Contributor

ChrisMcD1 commented Dec 3, 2025

As I tried to explain in #4301, this is not a direction I want to take.

Wow, I had forgotten that we actually had this discussion 🫣 In my memory, it was all an internal debate in my head with myself

I also briefly explored a total inversion of our whole MVC stack. That might be similar the more generic thing you are envisioning? The git updates would update the model, which then wholesale updated the view all at once. I remember it having a decent amount of duplication, since the model and the view needed their own copy of the data to work with, that the model couldn't be secretly mutating under the hood

@stefanhaller
Copy link
Collaborator Author

Hum, no, that doesn't sound like what I have in mind. I explained my proposal in #4301 (comment) and #2974 (comment).

I don't have time to go into more detail about this right now. It's going to be a pretty major undertaking, I'm planning to go about it at a point where I can devote a bit of focused time to it (which is not very soon 😄).

tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Dec 12, 2025
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [jesseduffield/lazygit](https://github.com/jesseduffield/lazygit) | minor | `v0.56.0` -> `v0.57.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>jesseduffield/lazygit (jesseduffield/lazygit)</summary>

### [`v0.57.0`](https://github.com/jesseduffield/lazygit/releases/tag/v0.57.0)

[Compare Source](jesseduffield/lazygit@v0.56.0...v0.57.0)

<!-- Release notes generated using configuration in .github/release.yml at v0.57.0 -->

#### What's Changed

##### Enhancements 🔥

- Open pull requests in browser with extra leading slashes removed by [@&#8203;hrzlgnm](https://github.com/hrzlgnm) in [#&#8203;5018](jesseduffield/lazygit#5018)
- Allow using SelectedSubmodule in CustomCommands by [@&#8203;rlkandela](https://github.com/rlkandela) in [#&#8203;5015](jesseduffield/lazygit#5015)
- Don't allow empty input in most prompts by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5043](jesseduffield/lazygit#5043)
- Suppress output from background fetch (unless there were errors) by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5044](jesseduffield/lazygit#5044)
- feat: add fork remote command by [@&#8203;karolzwolak](https://github.com/karolzwolak) in [#&#8203;4831](jesseduffield/lazygit#4831)
- Trigger immediate background fetch when switching repos by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5047](jesseduffield/lazygit#5047)

##### Fixes 🔧

- Keep cursor at top/bottom when navigating by page by [@&#8203;RaphaeleL](https://github.com/RaphaeleL) in [#&#8203;5019](jesseduffield/lazygit#5019)
- Switch to branches view when checking out a commit by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5048](jesseduffield/lazygit#5048)
- Fix deleting a remote tag when a remote branch with the same name exists, or vice versa by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5075](jesseduffield/lazygit#5075)
- Show fixup base commits in correct order in ctrl-f error message by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5073](jesseduffield/lazygit#5073)
- Band-aid fix for rare crashes when refreshing files by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5074](jesseduffield/lazygit#5074)
- Fix to support creating MRs for repositories cloned with SSH alias by [@&#8203;roveo](https://github.com/roveo) in [#&#8203;5082](jesseduffield/lazygit#5082)

##### Maintenance ⚙️

- Keep config and schema unchanged during a release by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5010](jesseduffield/lazygit#5010)
- Modernize all codes by [@&#8203;phanen](https://github.com/phanen) in [#&#8203;5036](jesseduffield/lazygit#5036)
- Bump golang.org/x/crypto from 0.37.0 to 0.45.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;5054](jesseduffield/lazygit#5054)
- Don't use "HEADLESS" environment variable for running tests by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5064](jesseduffield/lazygit#5064)
- refactor: use strings.Builder and strings.Repeat to simplify code by [@&#8203;boqishan](https://github.com/boqishan) in [#&#8203;5068](jesseduffield/lazygit#5068)
- chore: fix function name in comment by [@&#8203;riyueguang](https://github.com/riyueguang) in [#&#8203;4481](jesseduffield/lazygit#4481)

##### Docs 📖

- Add a "Commit history" section to CONTRIBUTING.md by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5022](jesseduffield/lazygit#5022)
- Update table of contents in README.md by [@&#8203;madscientist16](https://github.com/madscientist16) in [#&#8203;5045](jesseduffield/lazygit#5045)
- Update docs and schema for release by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5091](jesseduffield/lazygit#5091)

##### I18n 🌎

- Update translations from Crowdin by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5090](jesseduffield/lazygit#5090)

##### Performance Improvements 📊

- Fix and speed up the file list for the "Enter path to filter by" feature by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5056](jesseduffield/lazygit#5056)

#### New Contributors

- [@&#8203;hrzlgnm](https://github.com/hrzlgnm) made their first contribution in [#&#8203;5018](jesseduffield/lazygit#5018)
- [@&#8203;RaphaeleL](https://github.com/RaphaeleL) made their first contribution in [#&#8203;5019](jesseduffield/lazygit#5019)
- [@&#8203;rlkandela](https://github.com/rlkandela) made their first contribution in [#&#8203;5015](jesseduffield/lazygit#5015)
- [@&#8203;phanen](https://github.com/phanen) made their first contribution in [#&#8203;5036](jesseduffield/lazygit#5036)
- [@&#8203;madscientist16](https://github.com/madscientist16) made their first contribution in [#&#8203;5045](jesseduffield/lazygit#5045)
- [@&#8203;karolzwolak](https://github.com/karolzwolak) made their first contribution in [#&#8203;4831](jesseduffield/lazygit#4831)
- [@&#8203;boqishan](https://github.com/boqishan) made their first contribution in [#&#8203;5068](jesseduffield/lazygit#5068)
- [@&#8203;riyueguang](https://github.com/riyueguang) made their first contribution in [#&#8203;4481](jesseduffield/lazygit#4481)
- [@&#8203;roveo](https://github.com/roveo) made their first contribution in [#&#8203;5082](jesseduffield/lazygit#5082)

**Full Changelog**: <jesseduffield/lazygit@v0.56.0...v0.57.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi40Ny4wIiwidXBkYXRlZEluVmVyIjoiNDIuNDcuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90Il19-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

3 participants