When to use me
Use this skill for all version control operations. Prefer jj commands over git unless:
- •Jujutsu is not installed (
command -v jjfails) - •Performing git-specific operations not yet supported (e.g., submodules)
- •Working with CI systems that require raw git
Mental model
Jujutsu differs fundamentally from git:
- •Working copy is always a commit: No staging area.
@represents your current working-copy commit. - •Change IDs vs Commit IDs: Change IDs (e.g.,
kxryzmor) are stable across rebases. Prefer them for references. - •Bookmarks ≠ Branches: Bookmarks don't auto-advance on commit. You must explicitly move them.
- •Anonymous commits are normal: No branch/bookmark needed to start working.
- •History rewriting is first-class:
squash,split,rebaseare core workflows.
Preferred workflow: squash pattern
Separate intent (commit message) from implementation (working changes).
# 1. Create the described commit jj new main -m "feat: implement user authentication" # 2. Create a scratch child to work in jj new # 3. Make changes in the scratch commit # 4. When satisfied, squash into the parent jj squash # 5. Repeat steps 2-4 for additional changes
Multi-commit features
# First commit jj new main -m "refactor: extract auth module" jj new # ... work ... jj squash # Second commit as child of first jj new -m "feat: add JWT validation" jj new # ... work ... jj squash
Command reference
| Operation | Command |
|---|---|
| Status | jj status or jj st |
| Log | jj log |
| Current diff | jj diff |
| Show commit | jj show <change_id> |
| New commit | jj new |
| Describe | jj describe -m "message" |
| Squash into parent | jj squash |
| Abandon | jj abandon |
Git interop
| Operation | Command |
|---|---|
| Fetch | jj git fetch |
| Push bookmark | jj git push -b <bookmark> |
| Push all | jj git push --all |
Bookmark management
# Create/move bookmark to current commit jj bookmark set feature-name # Push to remote jj git push -b feature-name # After more work, must re-set bookmark before pushing again jj bookmark set feature-name jj git push -b feature-name
Git command translations
| Git | Jujutsu |
|---|---|
git status | jj status |
git diff | jj diff |
git commit -m "msg" | jj commit -m "msg" or jj describe -m "msg" && jj new |
git commit --amend | jj describe (message) or jj squash (content) |
git checkout -b feature | jj new -m "feature" |
git rebase main | jj rebase -d main |
git stash | jj new (old commit stays) |
git log --oneline | jj log --no-graph |
git reflog | jj op log |
git reset --hard | jj abandon |
Repository setup
Always use colocated repos for compatibility with git-expecting tools:
# New repo jj git init --colocate # Existing git repo cd existing-repo jj git init --colocate
Common workflows
Starting a feature
jj git fetch jj new main -m "feat: add widget support" jj new # ... work ... jj squash jj bookmark set add-widget-support jj git push -b add-widget-support
Updating with upstream
jj git fetch jj rebase -d main
Code review fixes
jj edit <change_id> # go to commit needing fixes jj new # scratch commit # ... make fixes ... jj squash jj bookmark set feature-name jj git push -b feature-name
Gotchas
- •
Bookmarks don't auto-advance: After
jj git push, runjj bookmark set <name>again before next push. - •
Colocated sync: Run
jj git exportif external tools aren't seeing changes,jj git importafter raw git commands. - •
Revset shortcuts:
@is current,@-is parent,@--is grandparent. - •
Undo anything:
jj undoreverts last operation.jj op logshows history. - •
Empty commits are fine: Unlike git, empty commits are normal placeholders.
- •
Conflicts are commits: Conflicts appear in the commit itself. Edit files to resolve, commit auto-updates.