How to uninstall GitButler's residual files and config that break standard git operations, GitButler app does not start
Version
0.20.4
Operating System
macOS
Distribution Method
dmg (Mac OS - Apple Silicon)
Describe the issue
Uninstalling GitButler leaves residual files and config that break standard git operations
Summary
After uninstalling GitButler, several files and configuration entries remain inside the repository's .git/ directory. These residuals interfere with normal git workflows — in particular, stale lock files prevent git commit, git add, and git push from running until they are manually removed. There is currently no documented cleanup path and no uninstall routine that removes them.
Environment
- OS: macOS (Apple Silicon)
- GitButler version: latest (Tauri app, installed via DMG)
- Uninstall method: Deleted GitButler.app from /Applications
Steps to Reproduce
- Install GitButler and connect it to an existing git repository.
- Use GitButler for normal development over several sessions (branch management, commits, pushes).
- Quit GitButler and delete GitButler.app from /Applications.
- Return to the repository and attempt standard git operations (
git add,git commit,git push).
What GitButler Leaves Behind
The following files and configuration remain after uninstalling the app. None are removed automatically.
.git/config — two injected stanzas
[gitbutler "project"]
targetRef = refs/remotes/origin/main
targetCommitId = <sha>
pushRemote = origin
portedMeta = true
[log]
excludeDecoration = refs/gitbutlerThe [gitbutler "project"] section is benign but confusing. The [log] excludeDecoration entry suppresses GitButler's internal refs from git log --decorate output — this is a side effect that persists silently after GB is gone.
.git/gitbutler/ — data directory (4 files)
.git/gitbutler/REFRESH
.git/gitbutler/but.sqlite
.git/gitbutler/gitbutler.write-lock
.git/gitbutler/virtual_branches.tomlgitbutler.write-lock is particularly problematic. If GitButler exits uncleanly (crash, force quit, or mid-operation uninstall), this file is left in a locked state. Subsequent git processes that inspect the .git/ directory can fail because of this stale lock.
.git/refs/heads/gitbutler/workspace — ghost branch ref
GitButler creates a gitbutler/workspace managed branch. After uninstall, this ref remains on disk:
.git/refs/heads/gitbutler/workspace
.git/refs/heads/gitbutler/workspace.lock ← stale lockThe workspace.lock here was the direct cause of git commit and git add failures in our case — git refused to proceed because it could not acquire a conflicting lock.
.git/logs/refs/heads/gitbutler/workspace — reflog entry
The reflog for the managed branch remains, creating clutter and referencing a branch that no longer has a meaningful owner.
.git/hooks/ — FUSE artifact from a removed hook
GitButler installs a post-checkout hook and removes it when leaving managed mode. On macOS with FUSE-mounted volumes, the deletion leaves a hidden file behind:
.git/hooks/.fuse_hidden0000007900000001This is a FUSE filesystem artifact (the file is still open when unlinked, so FUSE renames it instead of deleting it). It does not directly block git but accumulates across sessions.
.git/packed-refs.lock — stale lock
Left behind from a GitButler operation that did not complete its ref-packing cleanly. Blocks any git operation that needs to update packed refs.
Observed Impact
git commitfails:fatal: Unable to create '.git/index.lock': File exists.git commitfails:fatal: cannot lock ref 'HEAD': Unable to create '.git/HEAD.lock': File exists.git branch -D gitbutler/workspacefails:error: Unable to create '.git/packed-refs.lock': File exists.- All failures require manual
rmof lock files before git operations can proceed.
Expected Behavior
Uninstalling GitButler (or exiting it cleanly) should:
- Remove all stale lock files from
.git/before exit. - Remove the
[gitbutler "project"]section and the[log] excludeDecorationentry from.git/config. - Delete the
.git/gitbutler/directory, or at minimum releasegitbutler.write-lock. - Delete the
gitbutler/workspacebranch ref and its reflog. - Remove any hooks it installed.
If full cleanup on uninstall is not feasible, GitButler should provide a "Disconnect repository" action in the UI that performs this cleanup before the user removes the app.
Manual Cleanup
For anyone hitting this issue, the full cleanup is:
cd /path/to/your/repo
# Remove GitButler config stanzas
git config --remove-section 'gitbutler "project"' 2>/dev/null || true
git config --unset log.excludeDecoration 'refs/gitbutler' 2>/dev/null || true
# Remove GitButler data directory
rm -rf .git/gitbutler/
# Remove stale lock files
rm -f .git/index.lock
rm -f .git/HEAD.lock
rm -f .git/packed-refs.lock
# Remove the managed branch ref and its lock
rm -f .git/refs/heads/gitbutler/workspace
rm -f .git/refs/heads/gitbutler/workspace.lock
rmdir .git/refs/heads/gitbutler/ 2>/dev/null || true
# Remove reflog for managed branch
rm -f .git/logs/refs/heads/gitbutler/workspace
rmdir .git/logs/refs/heads/gitbutler/ 2>/dev/null || true
# Remove FUSE artifact from deleted hook (macOS only)
rm -f .git/hooks/.fuse_hidden*
# Delete the local managed branch (if it still appears in git branch -a)
git branch -D gitbutler/workspace 2>/dev/null || trueSuggested Fix
- Add a
teardown_repository(repo_path)function to the GitButler codebase that runs the above cleanup. - Call it on: (a) Disconnect repository action in the UI, (b) app quit if a repository is in managed mode, (c) a new CLI command
but teardownfor users who have already uninstalled the app. - Ensure
gitbutler.write-lockis always released in the Drop implementation of whatever struct holds it, so crashes don't leave it behind.
References
- Similar reports:
- GitButler log directory:
~/Library/Logs/com.gitbutler.app/ - FUSE unlink behavior on macOS: files open at unlink time are renamed to
.fuse_hidden*rather than deleted
How to reproduce (Optional)
No response
Expected behavior (Optional)
No response
Relevant log output (Optional)
Source: gitbutlerapp/gitbutler