Repository navigation
How Commit Options Work
The commit box has two controls next to the Commit button: an arrow with Commit & Push, Commit & Sync and Commit (Amend), and a gear with Commit Options (sign-off, author, GPG signing, skip hooks). This chapter shows how both reach git commit. The user side is in Commit Options.
People expect the commit dialog's options, and some projects require them: a Signed-off-by trailer for the Developer Certificate of Origin, signed commits on protected branches, or committing a patch in its author's name. "Commit and push" is the most common next step, so a dropdown saves a trip to the menu. Before, the only way to get these was the terminal.
commitOptions.svelte.ts holds the state and splits it on purpose:
-
Sign-off and GPG sign are preferences in
settings.json(commitSignOff, defaultfalse;commitGpgSign, default"default"). They describe how you sign your work everywhere, so they persist and also show in Settings > Git. -
Author and Skip hooks are session state per repository (
session[repoRoot]). They are one-off choices; forgetting them at quit means you never commit under someone else's name days later.
commitOptions.for(repoRoot) merges both into a CommitOptions object. CommitOptionsPopover.svelte edits it and shows a badge with changedOptionCount and a tooltip from commitOptionsTooltip, both built from the git arguments the options add.
Every commit path asks commitOptions.request(repoRoot) for what to send: commitRepo in views/changes/repoActions.ts (the Commit button, its arrow, the row's check mark and the ... Commit items) and commitCurrentFile in views/git/gitMenuActions.ts (Git > Current File > Commit File...).
sequenceDiagram
participant UI as Commit box or row
participant Opt as commitOptions.request
participant Api as api.ts
participant Rs as commands/status.rs
participant CO as commit_options.rs
participant Git as git CLI
UI->>Opt: request(repoRoot)
Opt->>Opt: validateAuthor, empty author becomes null
Opt-->>UI: CommitOptions, or null with a notice
UI->>Api: commit / commitAll / commitFiles(..., options)
Api->>Rs: invoke with options
Rs->>CO: options.args()
CO->>CO: author_error again, build arguments
CO-->>Rs: --signoff, --author=..., -S or --no-gpg-sign, --no-verify
Rs->>Git: commit [args] [--all] [--amend] -F -
commitOptionArgs in commitOptions.ts mirrors CommitOptions::args() in Rust, so the tooltip shows exactly what git will get. GPG has three states: default adds nothing (git's commit.gpgSign decides), sign adds -S, noSign adds --no-gpg-sign. The author goes as one argument, --author=Name <email>, so its text can never be read as another option.
commitDropdownItems and commitChoiceSpec in repoMenu.ts are pure. Each choice maps to { amend, followUp }:
| Choice | Amend | Follow-up |
|---|---|---|
| Commit | the Amend checkbox | none |
| Commit & Push | no | push(false, repoRoot) |
| Commit & Sync | no | syncRepo(repoRoot) |
| Commit (Amend) | yes | none |
commitRepo runs the follow-up only after the commit succeeded, so a refused commit (a failing hook, a bad author) never pushes. Push and Sync are disabled while the Amend checkbox is on, because pushing a rewritten commit needs a force push, and without a branch.
| File | What it does |
|---|---|
src/lib/views/changes/commitOptions.ts |
Pure: GPG choices, validateAuthor, commitRequest, commitOptionArgs, badge and tooltip |
src/lib/views/changes/commitOptions.svelte.ts |
The store: settings plus per-repository session options, request
|
src/lib/views/changes/CommitOptionsPopover.svelte |
The gear and its panel |
src/lib/views/changes/CommitBox.svelte |
The arrow and runChoice
|
src/lib/views/changes/repoMenu.ts |
commitDropdownItems, commitChoiceSpec
|
src/lib/views/changes/repoActions.ts |
commitRepo and its follow-up |
src-tauri/src/commands/commit_options.rs |
CommitOptions, GpgSign, author_error, args
|
src-tauri/src/commands/status.rs |
run_commit and run_commit_files add the arguments |
src/lib/stores/settingsData.ts |
commitSignOff and commitGpgSign defaults and validation |
Validate the author twice. The UI checks it as you type, to show the reason. Rust checks again because it builds the command line; a value that starts with - or lacks <email> is refused there no matter what the UI sent.
Options are arguments, not config. We never write user.name, commit.gpgSign or hooks settings. Arguments affect one commit and leave the user's git setup alone.
Default means "do what git does". The GPG default adds nothing, so a user who already signs through commit.gpgSign sees the same behavior as in the terminal.
The dropdown reuses Sync. Commit & Sync calls the same syncRepo as the Sync button, so pull conflicts stop it in the same way. See How Repository Actions Work.
-
src/lib/views/changes/commitOptions.test.ts: arguments per option, a blank author is left out, author rules match the backend. -
src/lib/views/changes/repoMenu.test.ts: the "commit dropdown" cases, choices to amend and follow-up, and what is disabled. -
src-tauri/src/commands/commit_options.rs:maps_each_option_to_its_argument,refuses_a_malformed_author. -
src-tauri/src/commands/status.rs:commit_options_sign_off_set_the_author_and_skip_hookscommits on a real repository and checks the trailer, the author and that a failing hook was skipped.
- A new option needs the same argument in
commitOptionArgsandCommitOptions::args(), a test on both sides, and a line in Commit Options. - Moving an option between settings and session state changes Settings too.
- Retake
commit-options.pngandcommit-dropdown.pngwhen the gear, its panel or the arrow look different.
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