2.7 KiB
Use jj instead of git or gt for all version control operations.
Custom revsets:
stackrepresents all the commits in the current stack (works even when the current commit is an empty child created byjj new)
Other key commands:
jj squash --from <id> --into <id> -- <paths>to move whole files between commitsjj split -r <id> -m <message> -- <paths>to split a commit (selected files stay, rest go to new child)jj describe <id> -m <message>to rename a commitjj diff -r <id> -- <path>to see a specific file's diff in a commitjj diff -r <id> --name-onlyto list changed filesjj log -r stackto see the current stack (stack is a custom revset described above)
Rebasing and conflicts:
- jj automatically rebases descendants when editing earlier commits. Expect cascading conflicts after modifying earlier commits, and resolve them working down the stack.
- Use the
new, ...,squashsequence when resolving conflicts.
Things to avoid:
- Avoid
jj absorb-- in a complex stack, it's likely to lose changes or put things into the wrong commits. - Avoid
jj edit <id>-- always prefer to open a new commit (jj new <id>) first.
Editing files
Before editing any files, always consider which new or existing commit the edits should be part of!
Edits should always be made in a new commit, and then squashed once they are finalized:
jj new <id>to open a new child of an existing commit- make the changes
jj squash --into <id> --use-destination-messageto squash into the existing commit
If the intent is to add a new commit rather than edit an existing one:
- use
jj new <id>where is the top commit of the stack - or use
jj new --insert-before <id>orjj new --insert-after <id>to insert a new commit mid-stack
When squashing or splitting, make sure that bookmarks stay attached to their original commits (because bookmarks map to PRs).
Pushing changes to GitHub/Graphite
Verify the stack first: Before pushing changes, always verify that there are no lingering temporary commits included in the stack revset. New commits that were intentionally introduced (intended to become new PRs) are fine. If there are lingering temporary commits, do not push; either resolve or get help from the user.
After verifying the stack:
- If the repo uses Graphite: use
jfdto push to Graphite. This submits all commits in thestackrevset as a 1:1 mapping of PRs to commits. - If the repo does not use Graphite: use
jj git push -c stackto push all commits in the stack (this creates an automatically-named branch for each commit). Then useghto create a PR for each branch.
To push a fresh commit (e.g. to retrigger CI), use jj metaedit --force-rewrite <id> to get a fresh commit hash, then push normally.