store last selected worktree, and open that when reselecting repo#106
Conversation
|
#105 might be interesting for you |
Cool yeah didn't see that, that looks good too! Something like this still might be valuable to have if people don't want to show the worktrees in the sidebar, e.g. if most of their repos only have one main worktree that they care about. But I'll leave that choice up to y'all, I'm fine either way. |
|
This currently has a small bug where returning to the main worktree from a linked worktree seems to do nothing the first time. On the second attempt it works fine. screenrecording-2026-03-27_21-53-47.mp4 |
Ty! just pushed a small change that should fix it |
|
Everything looks good now, thank you! |
|
This is now available in v3.5.7 |
Summary
When working with git worktrees, switching between repositories in the sidebar always lands on the main worktree, even if you were previously working in a linked worktree. This forces you to manually re-select your linked worktree every time you switch repos and come back — a significant friction point for worktree-heavy workflows.
This PR adds automatic worktree restore: the app remembers which worktree you were last using for each repository and automatically switches back to it when you return.
How it works
Preference storage (
worktree-preferences.ts— new file)A small
localStorage-backed store keyed by normalized main worktree path. Three operations:setPreferredWorktreePath(mainPath, activePath)— records the user's active worktree. If the active path is the main worktree, the entry is deleted (main is the default, so no preference needed).getPreferredWorktreePath(mainPath)— returns the stored preference, ornullto fall back to the main worktree.clearPreferredWorktreePath(mainPath)— removes the entry entirely.Recording the preference (
worktree-dropdown.tsx)When the user clicks a worktree in the dropdown,
setPreferredWorktreePathis called with the main worktree path and the selected worktree path after the repo switch succeeds. This ensures the preference is only persisted once the worktree has been successfully activated.Restoring the preference (
app-store.ts—_selectRepository)When
_selectRepositoryis called for a non-linked repository, the restore logic runs:This handles all cases: worktree already open, worktree directory exists but not yet added, and worktree was deleted outside the app.
Bug fixes
1. Stale preference after deletion of the currently-active worktree (
delete-worktree-dialog.tsx)Problem: The preference cleanup code called
getMainWorktreePath(repository)afterremoveWorktree()had already deleted the worktree from disk. When deleting the currently-active worktree, the code intentionally skipped the git call (the worktree is gone) and fell back torepository.path— which is the linked worktree path, not the main worktree path. Since preferences are keyed by the main worktree path, the lookup found nothing and the stale preference survived.Impact: This is a correctness/hygiene issue rather than a user-facing bug. The restore logic in
_selectRepositoryalready handles this gracefully — when it encounters a preferred path that no longer exists on disk, it clears the stale entry and falls back to the main worktree. So the preference self-heals on next visit, but lingers inlocalStorageuntil then.Fix: Resolve the main worktree path before the
removeWorktree()call while git metadata is still intact, and use that cached value in the cleanup afterward. TheisDeletingCurrentWorktreeternary is no longer needed.2. Worktree dropdown not refreshed after deleting a non-current worktree (
delete-worktree-dialog.tsx)Problem: After deleting a worktree that is not the currently selected one, the dialog dismissed without refreshing the repository state. The worktree dropdown continued showing the deleted worktree until the user switched away and back. Clicking the stale entry produced an "isn't a Git repository" error.
Fix: Added
await dispatcher.refreshRepository(repository)after the successfulremoveWorktree()call in the non-current-worktree path. This triggersgitStore.loadWorktrees(), which updates the dropdown immediately. The current-worktree deletion path doesn't need this becausedispatcher.selectRepository(mainRepo)already triggers a full refresh.3. Preference cleanup when a repository is removed from the app (
app-store.ts—_removeRepository)Problem: If a user removes a repository from GitHub Desktop (right-click → Remove), the
localStorageentry for that repo's preferred worktree persisted forever with no cleanup path.Fix: Added cleanup logic in
_removeRepositoryafter successful removal:Files changed
app/src/lib/worktree-preferences.tsapp/src/ui/toolbar/worktree-dropdown.tsxapp/src/lib/stores/app-store.ts_selectRepository; clean up in_removeRepositoryapp/src/ui/worktrees/delete-worktree-dialog.tsx