You stay on gitbutler/workspace always. Multiple virtual branches coexist in one directory. No switching, no stashing.
but status # what's going on
but branch new feat/thing # start a feature
but mark feat/thing # auto-route all new changes here
# ... write code ...
but commit feat/thing --ai # commit (AI message)
but commit feat/thing -m "message" # commit (manual message)
but push feat/thing # push
but pr new feat/thing # create PRbut branch new feat/a
but branch new fix/b
# edit files for both freely
but stage <file-id> feat/a # assign file to branch
but stage <file-id> fix/b
but commit feat/a --ai
but commit fix/b --aibut pull # fetch upstream, rebase all virtual branches
but pull --check # dry-run: can branches cleanly rebase?but merge feat/thing # merge virtual branch into local main
git push upstream main # push main (real branch, not virtual)but teardown # exit GitButler, snapshot state
git checkout main
git pull upstream main
# ... rebase, merge, fix conflicts ...
git push upstream main
but setup # re-enter GitButler, restore everythinggh pr diff 123 # read diff (no checkout needed)
gh pr view 123 # view PR details
gh pr checkout 123 # need to run code? leaves workspace
git checkout gitbutler/workspace # come back when donebut undo # undo last operation
but oplog # view full operation history
but oplog restore <sha> # restore to any pointGitButler wraps hooks in .husky/_/ (gitignored, local-only). Your Husky lint-staged setup runs normally. Other contributors are unaffected. but teardown auto-restores original hooks.
- Use
butfor writes (commit, push, branch, stage) - Use
gitfor reads (log, diff, blame, status) - Use
ghfor collaboration (PR review, checkout) - Never
git commitorgit checkoutongitbutler/workspace