jesseduffield / jesseduffield/lazygit
Recent repos menu can't return to a repo opened with --git-dir/--work-tree (dotfile repos)
- Dominant language
- Go
- Stars
- 82.4k
- Forks
- 3k
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 19
Description
## Describe the bug
The recent repositories menu (`ctrl+r`) cannot bring you back to a dotfile-style repo — one whose git dir doesn't live at `/.git`, opened with `--git-dir`/`--work-tree` (yadm) or found through `core.worktree` (vcsh). #5910 fixed this class of problem for the in-session repo-path stack (entering/escaping submodules), but the persistent recent-repos list still only stores paths, so such a repo effectively falls out of repo switching:
1. **The entry disappears from the menu.** `newRecentReposList` (`pkg/gui/recent_repos_panel.go`) keeps an entry only if `/.git` exists. A dotfile repo's work tree has no `.git`, so the next time lazygit runs in any other repo, the entry is dropped from the list.
2. **Even when the entry is still there, switching fails.** The menu's `OnPress` calls `switchTo(path)`, which clears `GIT_DIR`/`GIT_WORK_TREE` and chdirs to the path; `VerifyInGitRepo` then fails with "must be run inside a repository", because nothing at the work tree's path leads to the git dir.
3. The root cause is that `AppState.RecentRepos` is `[]string` — there is nowhere to remember *how* the repo was found. The old comment in `updateRecentRepoList` ("we could totally do this but it would require storing both the git-dir and the worktree in our recent repos list, which is a change that would need to be backwards compatible", from e8738161, 2020) describes exactly this gap; #5910's `RepoLocation.GitLocationEnvVars` now provides the mechanism, the recent-repos list is just not wired up to it.
The startup path has the same blind spot: `openRecentRepo` in `pkg/app/app.go` checks `/.git` and silently skips dotfile repos when offering to open the most recent repo.
## To reproduce
```sh
mkdir -p ~/tmp/project/repo && cd ~/tmp/project/repo
git init --bare ../.bare
git --git-dir=../.bare --work-tree=. checkout -b main
touch blah && git --git-dir=../.bare --work-tree=. add blah
git --git-dir=../.bare --work-tree=. commit -m 'initial commit'
lazygit --git-dir=$PWD/../.bare --work-tree=$PWD
# ctrl+r, switch to any previously visited normal repo — this works
# ctrl+r again — the dotfile repo is not in the menu anymore
# (on older state where the entry still exists, selecting it errors instead)
```
## Expected behavior
Switching away from a dotfile repo and back again through the recent repositories menu round-trips, the same way entering and escaping a submodule now does after #5910.
## Notes on a possible fix
I have a working patch on a fork branch, linked purely as a reference — I've read CONTRIBUTING.md and I'm not posting a PR: https://github.com/xooooooooox/lazygit/tree/fix-recent-repos-git-location
It adds `RecentRepoGitLocations map[string][]string` to `AppState` alongside `RecentRepos` (backwards compatible in both directions — old binaries ignore the unknown key, new binaries tolerate its absence), records `RepoPaths.GitLocationEnvVars()` in `updateRecentRepoList`, relaxes the `.git` existence filter to also accept entries with a recorded git dir, and has the menu switch through `switchToLocation` with the recorded env vars. The `IsBareRepo()` early-out can then also be narrowed to bare repos *without* a work tree, which resolves the 2020 comment. Covered by two integration tests (`--git-dir`+`--work-tree` and `core.worktree` flavours).
## Version info
Reproduced on master (c199ac69) and v0.64.1.
Contributor guide
Research direction
Start with pkg/gui/recent_repos_panel.go and pkg/app/app.go, tracing AppState.RecentRepos, updateRecentRepoList, openRecentRepo, and the menu's switchTo path. Read RepoPaths.GitLocationEnvVars and the two integration-test cases mentioned for --git-dir/--work-tree and core.worktree repositories. Done means a dotfile-style repository remains in recent repos and round-trips through the menu and startup flow.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, go
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100