Repository navigation
How Ignoring Files Works
Add to .gitignore in the Files panel and the Changes list writes an ignore pattern for a file, its folder or its extension, to the shared .gitignore or to the local .git/info/exclude, and offers to stop tracking files the pattern now matches. Edit .gitignore opens the file. The user side is in Ignoring Files.
Writing a correct pattern by hand is easy to get wrong: a pattern without a leading / matches at every depth, and characters like *, [ or a leading # change its meaning. People also expect an ignored file to disappear from Changes, but git keeps tracking a file that is already committed. Both are solved from a right-click; this is the same.
sequenceDiagram
participant Menu as Files panel or Changes row
participant IA as ignoreActions.ts
participant GI as gitignore.ts
participant Cmd as commands/ignore.rs
participant Git as git
Menu->>IA: ignoreMenu(repoRoot, repoRelativePath, isDir)
IA->>GI: ignoreChoices(path, isDir)
GI-->>IA: file, folder and extension patterns, escaped
Note over Menu: the user picks a pattern and a target
IA->>Cmd: add_to_ignore(patterns, target, filePaths)
Cmd->>Cmd: append missing lines in the file's own line ending
Cmd->>Cmd: tracked index entries the patterns now ignore
Cmd-->>IA: IgnoreOutcome with added, existing, trackedPaths
IA->>IA: confirm Remove from Git? (danger)
IA->>Cmd: untrack_files(trackedPaths)
Cmd->>Git: rm --cached -r -q, paths on stdin, literal
src/lib/ignore/gitignore.ts is pure. ignoreChoices returns, for a file, filePattern (/src/wishlist.ts), folderPattern of its parent (/src/, skipped at the root) and extensionPattern (*.ts, skipped for names like Makefile or .env). A folder gets only its own folderPattern. The repository root gets nothing, so ignoreMenu returns null and the menu leaves the item out.
escapeIgnoreText makes a path literal for gitignore(5): a backslash before *, ?, [ and \, before a leading # or ! when the text starts the line (the menu's patterns start with / or *., so there they stay plain), and before trailing spaces, which git would drop. A name with a line break cannot be a pattern, so it is left out.
run_add_to_ignore in src-tauri/src/commands/ignore.rs checks the patterns (no empty or multi-line ones), resolves every scope path with safe_join, and picks the file: the work tree's .gitignore, or info/exclude under commondir() so linked worktrees share it. append_patterns adds only the lines that are missing, in CRLF when the file already uses CRLF, and adds a newline first when the file does not end with one. The outcome lists what was added and what was there already, which the toast reports.
A pattern does not untrack anything. tracked_matches opens a fresh repository handle (so the new patterns are read), walks the index, keeps entries inside the scope paths or with a *.ext pattern's literal extension, and asks git2's status_should_ignore whether git now ignores them. At most MAX_TRACKED (1000) are returned. If any are, offerUntrack asks with a danger confirm, then untrack_files runs git --literal-pathspecs rm --cached -r -q --pathspec-from-file=- --pathspec-file-nul, so the list never hits the command line limit and a * in a name is never a glob.
Edit .gitignore calls ensure_ignore_file, which creates an empty file when there is none and returns its path, and opens it pinned in an editor tab.
| File | What it does |
|---|---|
src/lib/ignore/gitignore.ts |
Pure escaping and pattern choices, KIND_HINTS
|
src/lib/ignore/ignoreActions.ts |
ignoreMenu, addToIgnore, offerUntrack, editIgnoreFile
|
src-tauri/src/commands/ignore.rs |
add_to_ignore, ensure_ignore_file, untrack_files, append_patterns
|
src/lib/views/files/explorerMenu.ts |
Adds the submenu to file and folder menus (not for deleted rows) |
src/lib/views/changes/RepoSection.svelte |
Adds it to Changes and Staged rows (not to conflicts) |
Anchored patterns. A leading / ignores exactly the thing you right-clicked. An unanchored wishlist.ts would also ignore a file of that name in every folder, which surprises people. The extension choice is the one deliberate "everywhere" pattern.
Only the root .gitignore. Nested ignore files are valid, but one file per repository is easier to find and to review. Patterns are relative to it, so they stay correct.
Ask before untracking. git rm --cached shows up as a deletion for everyone who pulls it, so it is never done silently, and the dialog says the files stay on disk.
The UI escapes, the backend validates. Patterns are text the user picks from a menu, so escaping lives with the menu and is tested there. The backend still refuses anything that would break the file.
-
src/lib/ignore/gitignore.test.ts: plain paths and unicode, glob characters and backslashes, a leading#or!and trailing spaces, names a line cannot hold, anchored file and folder patterns, extensions but not dotfiles, and the choices per file and folder. -
src-tauri/src/commands/ignore.rs:appends_once_with_a_newline_in_the_files_own_style,reads_literal_extensions,adds_to_gitignore_and_reports_tracked_matches,adds_to_info_exclude_and_creates_files_for_editing,untracks_names_with_glob_characters_literally,refuses_patterns_that_would_break_the_file.
- Update this page and Ignoring Files when a choice, a target or the untrack step changes, with a test on the matching side.
- Retake
gitignore-menu.pngwhen the submenu changes. - The menus are documented in Files Panel and Changes and Commits.
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