Repository navigation
How the Git Dialogs Work
The Git menu opens dialogs for Push, Pull, Update Project, Merge, Rebase, Reset HEAD, Rollback, Manage Remotes and Clone. This chapter explains how they are shown, where their rules live and how a clone can be cancelled. The user side is in Git Dialogs; the menu that opens them is in How the Git menu works.
One-click buttons are fine for a plain push or pull, but git has options people need now and then: push to another branch, pull with rebase, merge with --no-ff, reset in Keep mode. We show those in small dialogs, with the commits that will move and a preview of the exact git command, which also teaches git.
flowchart LR
Menu["Git menu, Changes ... menu,<br/>Branches popup"] --> Store["gitDialogs.open({ kind, repoRoot })"]
Store --> Host["GitDialogHost.svelte<br/>mounts it fresh"]
Host --> Dialog["PushDialog, PullDialog, ..."]
Dialog --> Frame["Dialog from the UI library:<br/>Esc, Cmd+Enter, focus"]
Dialog --> Confirm["dialogs.confirm on top"]
Dialog --> Run["repoStore.runOp / run"]
Run --> Api["api.ts to Rust commands"]
gitDialogs.svelte.ts holds the one open dialog as a tagged value (push, pull, reset, rollback, remotes, clone, update, merge, rebaseBranch, rebase, plus the ones other chapters cover). GitDialogHost.svelte renders it inside {#key active}, so every open mounts fresh and starts from the repository's current state.
Each dialog is the UI library's Dialog with variant="form" (see UI-Library.md), and its body is built only from library parts: Field, Input, Select, RadioGroup, Checkbox, ListBox, CodeBlock for the command preview, Text and Stack. The dialog draws the overlay, title, scrolling body and footer; Escape cancels, Cmd+Enter (Ctrl+Enter) runs the main action, and the first field (or the one marked autofocus) gets the focus. It handles keys on its own element, so a confirmation from dialogs (DialogHost) on top keeps its keys, and dismissible={false} keeps it open while work runs, as during a clone. While a Git dialog is open, guarded menu items and window shortcuts do nothing (shortcutsBlocked).
The dialog closes before the git command runs. repoStore.runOp and run then show the busy state, the toast and refresh the status, like every other git action.
The rules are in pure, tested modules, so the Svelte files only wire them up:
-
gitOptions.ts: the default push target (the upstream, else the same name onoriginor the first remote),pushCommand,PULL_MODESandpullCommand,RESET_MODES, name, URL and revision checks,cloneFolderName(git's "humanish" folder name),updatePlanandrollbackPaths. -
integrateOptions.ts: the Merge and Rebase flags, which options exclude each other (toggleMergeFlag,toggleRebaseFlag),validateRebase, the request sent to Rust andmergeCommand/rebaseCommand.
The previews are built from the same values the backend gets, and commands/integrate.rs builds the same arguments. The backend checks again: it refuses option combinations that make no sense and names that start with - (reject_option).
| Dialog | Commands |
|---|---|
| Push |
outgoing_commits (refreshed 200 ms after the target changes), push_with_options
|
| Pull |
pull_with_options with merge, rebase or ff-only and --no-commit
|
| Update Project |
pull_with_options per repository, one after another |
| Merge, Rebase |
merge_with_options, rebase_with_options; --interactive asks rebase_plan_onto
|
| Reset HEAD |
resolve_revision while typing, reset_to with soft, mixed, hard or keep |
| Rollback |
rollback_files with the ticked paths and "delete added" |
| Manage Remotes |
list_remotes, add_remote, edit_remote, remove_remote
|
| Clone |
clone_repository with a progress Channel, cancel_git_command
|
Update Project runs updateProject in gitMenuActions.ts: updatePlan lists the repositories with an upstream (others are skipped with a reason), then each one is pulled in order with the label "Updating 2 of 5: name". It stops at the first conflict or failure and says how many were not updated. The method is saved as the updateMethod preference.
sequenceDiagram
participant Dialog as CloneDialog
participant Rust as clone_repository
participant Cancel as git/cancel.rs
participant Git as git clone
Dialog->>Rust: url, folder, progress Channel, cancelId
Rust->>Cancel: run_streaming(args, cancelId)
Cancel->>Git: spawn in its own process group
Git-->>Dialog: progress lines
Dialog->>Cancel: cancel_git_command(cancelId)
Cancel->>Git: SIGTERM to the group
Git-->>Rust: exits
Rust->>Rust: clean_cancelled_clone
Rust-->>Dialog: error "Clone cancelled", shown as a notice
cancel.rs keeps a registry of running commands by cancel id. git runs in its own process group, so the signal also stops its helpers (git-remote-https, index-pack). It gets SIGTERM, not SIGKILL, so it can clean up; on Windows the child is killed. A process that was already reaped is never signalled, since its pid may belong to another process by then. clean_cancelled_clone removes the folder only if the clone created it; a folder that existed (and was empty) only loses what the clone put in it.
| File | What it does |
|---|---|
src/lib/views/git/gitDialogs.svelte.ts, GitDialogHost.svelte
|
The store and the host |
ui/web/src/lib/components/Dialog.svelte |
The frame every Git dialog uses (library) |
src/lib/views/git/PushDialog.svelte, PullDialog.svelte, UpdateProjectDialog.svelte
|
Remotes |
src/lib/views/git/MergeDialog.svelte, RebaseBranchDialog.svelte
|
Merge and Rebase |
src/lib/views/git/ResetDialog.svelte, RollbackDialog.svelte
|
Reset and Rollback |
src/lib/views/git/RemotesDialog.svelte, CloneDialog.svelte
|
Remotes and Clone |
src/lib/views/git/gitOptions.ts, integrateOptions.ts
|
Pure rules and previews |
src-tauri/src/commands/remote.rs |
Push, pull, fetch, remotes, clone |
src-tauri/src/commands/integrate.rs |
Merge and rebase with options |
src-tauri/src/commands/history.rs |
Reset and revisions |
src-tauri/src/git/cancel.rs |
Cancellable streaming commands |
A store of its own. Git dialogs are bigger than the prompts in dialogs, and they need those prompts on top of them (Force Push, Hard Reset). Two stores keep that simple.
Mount fresh every time. {#key active} means no stale branch or remote from the last open.
Show the command. The preview costs little and makes every option's effect clear.
Confirm what loses work. Force push, Hard reset, Rollback and Remove Remote ask again with a red button, as the project rules require.
Update one repository at a time. One busy state, a clear progress label, and a stop at the first conflict, so you never face conflicts in several repositories at once.
Screen readers read the Browse button as part of the folder field. Found while driving the Clone dialog with Windows UI Automation: the folder field was named "Clone into folder Browse...". A <label> names its field with all the text inside it, and these labels also hold a button. The fields with a button beside them (Clone, New Worktree, Merge, Reset, Rebase) now carry an aria-label with just their label text. We kept the wrapping labels, so a click on the label text still focuses the field.
-
src/lib/views/git/gitOptions.test.ts: push targets and preview, pull modes, reset modes, revision, name, URL and folder checks, the update plan and rollback paths. -
src/lib/views/git/integrateOptions.test.ts: excluded options, requests and previews, rebase forms and--interactive. -
src-tauri/src/commands/remote.rs: pull and push with options, outgoing commits, remotes,clone_goes_into_a_missing_or_empty_folder_onlyandcancelling_a_clone_removes_only_what_it_created. -
src-tauri/src/commands/integrate.rs: every merge option, bad combinations, and rebase with--onto,--rootand the other flags. -
src-tauri/src/commands/history.rs:reset_keep_moves_the_branch_and_keeps_local_changes,resolve_revision_finds_branches_tags_and_hashes. -
src-tauri/src/git/cancel.rs:cancel_stops_the_command_and_its_children.
The dialogs' layout needs a visual check. See Testing.
- A new option goes in the pure module with a test, in the Rust command and in the preview.
- Update Git Dialogs and retake the dialog screenshots (
git-*-dialog.png). See Docs and Screenshots.
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