Repository navigation
How the Branches Popup Works
The Branches popup is a branch list: a filter, New Branch, Checkout Tag or Revision, then local and remote branches, each with a submenu of actions. It opens from a repository's branch button in Changes and from Git > Branches.... Two of its actions open editor tabs: Compare with the current branch, and Show Diff with Working Tree. The user side is in Branches Popup.
The Branches sidebar shows only the active repository and acts through right-click menus. People expect one keyboard-friendly list per repository, with actions the sidebar never had: update a branch you are not on, push it, change what it tracks, compare it with yours. Opening it from each repository row also means no switch of the active repository, which would reload branches and history.
openBranchPicker(repoRoot) in views/changes/repoActions.ts calls gitDialogs.open({ kind: "branches", repoRoot }). GitDialogHost.svelte renders BranchesPopup.svelte, which sits in the UI library's Dialog, the frame every Git dialog uses (title, Esc, footer). The list is the library's List driven by the filter field (fieldKeys="drive"): the field keeps the focus while Up and Down move the highlight, Enter opens the highlighted branch, and branchListItems adds the Local and Remote headings, which the list skips. The popup loads refs with loadDetails, which reuses repoStore.refs for the active repository and calls getRefs for any other. For the active repository an effect keeps the list fresh after an action.
filterBranches(refs, query) in branchPopup.ts keeps branches whose name contains every word of the query and puts the current branch first. trackingHint gives the row hint, such as "origin/main, 1 ahead".
localBranchActions(branch, context) and remoteBranchActions(remoteBranch, context) are pure: they return the rows (labels with the branch names filled in, disabled, danger, hint) from a BranchPopupContext of the current branch, busy, operation in progress and whether remotes exist. branchMenuItems in branchPopupActions.ts maps each BranchAction to code and closes the popup first. The submenu itself is a contextMenu anchored at the row's right edge, so it gets the menu's keyboard handling for free.
flowchart TD
A["Branch row: click, Enter or Right"] --> B{"local or remote?"}
B -->|"local, current"| C["New Branch, Update, Push..., Track Remote, Unset Upstream, Rename"]
B -->|"local, other"| D["Checkout, New Branch, compare and integrate, Update, Push, Rename, Delete"]
B -->|"remote"| E["Checkout, New Branch, compare and integrate"]
D --> F["againstCurrent: Checkout and Rebase, Compare, Diff with Working Tree, Rebase onto, Merge..."]
E --> F
With a detached HEAD there is no current branch, so againstCurrent offers only Show Diff with Working Tree.
| Action | Code | git |
|---|---|---|
| Checkout, New Branch, Rename, Delete, Rebase onto |
sidebar/actions.ts with a RepoTarget
|
as in How Branches and Tags Work |
| Merge... | gitDialogs.open({ kind: "merge" }) |
the Merge dialog |
| Checkout and Rebase onto | checkoutAndRebase |
rebaseWithOptions with onto and branchName (a remote branch is checked out as its tracking branch first) |
| Update, other branch | update_branch |
fetch <remote> <upstream>:<branch>, refused unless a fast-forward |
| Update, current branch | pull_with_options |
pull --no-rebase or --rebase, from the updateMethod setting |
| Push, other branch | push_branch |
push <remote> refs/heads/<b>:<upstream>, or -u to the default remote |
| Push..., current branch | the Push dialog | see How the Git Menu Works |
| Track Remote Branch..., Unset Upstream |
set_branch_upstream, unset_branch_upstream
|
branch --set-upstream-to, branch --unset-upstream
|
The new commands live in src-tauri/src/commands/branch_actions.rs. Branch names pass reject_option, so a name can never be read as a flag.
Compare and Show Diff open pseudo tabs, like commit tabs (see How Commit Tabs Work). branchTabPath in stores/branchTabs.ts encodes the reference as branches-compare:<repo>|<branch>|<base> or branches-worktree:<repo>|<revision> (and branches-changes:<repo> for the status bar's Changes tab), URI-encoded, never starting with /, so it cannot clash with a file. branchTabTitle names the tab ("fix/tax-rates vs main") and branchTabsInFolder closes them with their workspace folder.
-
BranchCompareTab.sveltecallscompare_branches: commits in each side and not the other (at mostMAX_COMPARED, 1000, thentruncated) and the changed files. A file's diff comes fromrevisions_file_diff, the base on the left. -
WorktreeDiffTab.sveltecallscompare_with_worktree(untracked files count as added) andcompare_with_revisionper file. It reloads when the repository's status object changes.
Both share BranchFileList.svelte and the normal DiffView.
| File | What it does |
|---|---|
src/lib/views/git/BranchesPopup.svelte |
The popup: filter, actions, list, keyboard, submenu anchor |
src/lib/views/git/branchPopup.ts |
Pure: filter, hints, the submenu rows |
src/lib/views/git/branchPopupActions.ts |
What each action runs |
src/lib/views/git/BranchCompareTab.svelte, WorktreeDiffTab.svelte, BranchFileList.svelte
|
The two tabs |
src/lib/stores/branchTabs.ts |
Pseudo tab paths, titles, folder cleanup |
src-tauri/src/commands/branch_actions.rs |
Update, push, upstream and compare commands |
Update without checkout uses a fetch refspec. git fetch origin main:main moves a branch that is not checked out, and git refuses anything but a fast-forward. No checkout, no touched files, no lost commits.
Close the popup before acting. Dialogs such as Rename or Merge then open on a clean screen, and a long operation shows its progress in the header rather than under a popup.
Pure rows, tested. Which items exist and when they are disabled is the part that grows, so it lives in branchPopup.ts with tests, and the component only renders.
-
src/lib/views/git/branchPopup.test.ts: actions for another local branch, the current branch and a remote branch, and filtering with the current branch first. -
src/lib/stores/branchTabs.test.ts: paths round-trip, other paths are refused, titles and folder cleanup. -
src-tauri/src/commands/branch_actions.rs:update_fast_forwards_a_branch_without_checking_it_out,push_branch_publishes_and_then_pushes_to_the_upstream,upstream_is_set_and_unset,compares_commits_and_files_between_branches,compares_a_branch_with_the_working_tree.
- Update this page and Branches Popup when an action, a disabled rule or a tab changes, with a case in
branchPopup.test.ts. - Retake
branches-popup.pngandbranches-compare-tab.pngwhen they look different. - Related: How Repository Actions Work, How Branches and Tags Work.
None yet.
These pages are generated from docs/wiki. To correct something, open a pull request against the source file; edits made here are overwritten.
Using Nibtree
- Getting Started
- Welcome Screen
- Workspaces
- Files Panel
- File Operations
- File Icons
- Rounded Panels
- Editor and Tabs
- Pin Reorder and Wrap Tabs
- Single Tab Title
- Split Editor
- New File and Unsaved Changes
- Unload Hidden Tabs
- Editing Code
- Code Appearance
- Markdown Editor
- Image and PDF Preview
- Search Everywhere
- Recent Files
- Navigation Bar
- Find and Replace
- Changes and Commits
- Sign In Prompts
- Commit Box Layout
- Repository Actions
- Commit Options
- Ignoring Files
- Diffs
- Inline Diffs
- Staging View
- Revert a Change
- Resolving Conflicts
- Merge Tool
- Blame
- History and Log
- Merge Commits
- Branches and Tags
- Branches Popup
- Remotes
- Stashes
- Shelf
- Git Menu
- Git Dialogs
- Interactive Rebase
- Worktrees
- AI Agents
- AI Tasks
- AI Usage
- Keep Computer Awake
- Submodules
- Git LFS
- GitHub
- Git Console
- Terminal
- Terminal Features
- Scripts
- Navigation
- Menus
- Settings
- Settings Search
- Color Themes
- Settings Terminal and Automation
- Settings Files
- Updates
- Status Bar and Help
- Notifications
- Memory Use
- Clear Cache
- MCP and CLI
- Git Mergetool
- Keyboard Shortcuts
- Keyboard Shortcuts Editor
- Troubleshooting
- Troubleshooting Git
Developers
- Developer Guide
- Architecture
- Project Layout
- Backend
- How Folder Watching Works
- Folder Watching Bugs We Fixed
- How Workspace Files Work
- How the Preview Scheme Works
- Backend Services
- How Terminal Features Work
- Terminal Bugs We Fixed
- Frontend
- How the Rich Markdown Editor Works
- Rich Markdown Bugs We Fixed
- Git Menu Links
- Menu Keys and Routing
- Frontend Modules
- Blame Bugs We Fixed
- Project Color And Title Bar
- One Diff View
- Diff Bugs We Fixed
- Merge Tool Layouts
- Merge Tool Bugs We Fixed
- Color Theme Bugs We Fixed
- How the Connected Diff Works
- Rounded Panels Bugs We Fixed
- Update Bugs We Fixed
- Status Bar Bugs We Fixed
- MCP and CLI Bugs We Fixed
- Repository Actions Bugs We Fixed
- How the Changes Tab Works
- CodeMirror Patterns
- How the Cursor Works
- How Editor Features Work
- How the Path Bar Works
- Commands and Events
- Settings Reference
- Commands Workspace and Changes
- Commands Branches and Remotes
- Commands History and Extras
- Commands App and Tools
- Testing
- Test Suites
- Debugging
- Debugging with MCP
- Measuring Setting Memory
- How Terminal Memory Is Measured
- How Markdown Diagrams Work
- Releases and CI
- Publishing the Wiki
- Versioning and Changelog
- Browser Version Packages
- Browser Release Checks
- Docker Image
- Platforms and Signing
- Windows Support
- Windows Bugs We Fixed
- Windows MCP and CLI
- Docs and Screenshots
- UI Library
- UI Library MCP
- UI Library Bugs
- UI Library Migration
- Contributing
How features work
- Welcome screen
- Workspaces and folders
- Files panel
- File operations
- File icons
- Editor and tabs
- Pin, reorder and wrap tabs
- Single tab title
- Split editor
- New File and unsaved changes
- Unload hidden tabs
- Editing code
- Code appearance
- Markdown editor
- Image and PDF preview
- Search Everywhere
- Recent Files
- Navigation Bar
- Find and replace
- Changes and commits
- Sign-in prompts
- Commit box layout
- Repository actions
- Commit options
- Ignoring files
- Diffs
- Inline diffs
- Staging view
- Revert a change
- Resolving conflicts
- Merge tool
- Blame
- History and log
- Merge commits
- Commit tabs
- Branches and tags
- Branches popup
- Remotes
- Stashes
- Shelf
- Git menu
- Git dialogs
- Interactive rebase
- Worktrees
- AI agents
- AI usage
- Keep computer awake
- AI tasks
- Submodules
- Git LFS
- GitHub account
- Git Console
- Back and Forward
- Integrated terminal
- Scripts tool window
- Menu bar
- Settings
- Search in Settings
- Color themes
- Rounded panels
- Updates and release channels
- Status bar and help links
- Notifications
- Memory readout and memory log
- Clear Cache
- MCP server and command line tool
- git mergetool mode