Use `jj` instead of `git` or `gt` for all version control operations. Custom revsets: - `stack` represents all the commits in the current stack (works even when the current commit is an empty child created by `jj new`) Other key commands: - `jj squash --from --into -- ` to move whole files between commits - `jj split -r -m -- ` to split a commit (selected files stay, rest go to new child) - `jj describe -m ` to rename a commit - `jj diff -r -- ` to see a specific file's diff in a commit - `jj diff -r --name-only` to list changed files - `jj log -r stack` to 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`, ..., `squash` sequence 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 ` -- always prefer to open a new commit (`jj new `) 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 ` to open a new child of an existing commit - make the changes - `jj squash --into --use-destination-message` to squash into the existing commit If the intent is to *add* a new commit rather than edit an existing one: - use `jj new ` where is the top commit of the stack - or use `jj new --insert-before ` or `jj new --insert-after ` 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 `jfd` to push to Graphite. This submits all commits in the `stack` revset as a 1:1 mapping of PRs to commits. - If the repo does not use Graphite: use `jj git push -c stack` to push all commits in the stack (this creates an automatically-named branch for each commit). Then use `gh` to create a PR for each branch. To push a fresh commit (e.g. to retrigger CI), use `jj metaedit --force-rewrite ` to get a fresh commit hash, then push normally.