Help us shape the future of Go! Take the 2026 Go Developer Survey

jj-diff

module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 17, 2026 License: MIT

README

jj-diff

demo

Read a Jujutsu diff in the terminal and move parts of it around: pick hunks or individual lines and send them to another revision, or split one commit into several focused ones. Drops in as jj's diff editor for jj split, jj diffedit, jj amend -i, and jj squash -i, so it works the same whether you run it from a plain jj command line or from a TUI that shells out to one (jj-tui, jjui, lazyjj).

Alternatives

jj-diff is narrow on purpose: hunk and line moves between revisions, and splitting. For adjacent problems, one of these may fit better:

Tool Notes
crecord "allows you to interactively choose among the changes you have made, and commit only those changes you select" (Mercurial)
Delta "A syntax-highlighting pager for git, diff, grep, rg --json, and blame output"
Difftastic "a structural diff that understands syntax"
git add -p "interactively choose hunks of patch between the index and the work tree and add them to the index" (built into Git)
gitui "Blazing fast terminal-ui for git written in rust"
jj's built-in diff editor (scm-record) "a UI component to interactively select changes to include in a commit. It's meant to be embedded in source control tooling"
jjui "A TUI designed for interacting with the Jujutsu version control system"
KDiff3 "Utility for comparing and merging files and directories"
lazygit "simple terminal UI for git commands"
lazyjj "TUI for Jujutsu/jj. Built in Rust with Ratatui. Interacts with jj CLI"
Magit "A Git Porcelain inside Emacs"
Meld "Meld is a visual diff and merge tool targeted at developers"
tig "Text-mode interface for git"
vimdiff Runs any diff as a Vim or Neovim split through git difftool, built into Git
awesome-jj "A curated list of awesome Jujutsu things"

Install

# Homebrew
brew install --cask kyleking/tap/jj-diff
# Go
go install github.com/kyleking/jj-diff/cmd/jj-diff@latest
# from source
mise install && hk install --mise && mise run build

Quick start

Move a few lines from the working copy into the previous commit:

jj-diff --interactive

Press d and pick @- as the destination, n to reach the hunk, v for line-level selection, space to confirm the lines, and a to apply. Press ? at any point for the keymap.

What it does not do

  • Work on a plain git repository. It shells out to jj, so a repo needs jj 0.9.0+
  • Overwrite your working copy. Every patch is built in a scratch workspace, so an abandoned run cannot cost you unselected changes. Splitting to a new commit is the one step that touches your working copy, and it only moves the parent pointer, the same way jj split does
  • Commit, rebase, or edit commit descriptions. It moves existing changes between revisions and nothing else
  • Browse the repository. There is no change graph, operation log, or bookmark management here. That is jj-tui's job, and jjui's, and both hand hunk-level work to a diff editor, which is where jj-diff fits
  • Resolve merge conflicts
  • Edit file contents. You choose which existing changes move, and you do not type new ones

Full docs: ./docs

License

MIT

Directories

Path Synopsis
cmd
jj-diff command
Command jj-diff is a terminal diff viewer for Jujutsu.
Command jj-diff is a terminal diff viewer for Jujutsu.
internal
components/commitmsg
Package commitmsg prompts for the commit message of one split tag during a multi-split.
Package commitmsg prompts for the commit message of one split tag during a multi-split.
components/destpicker
Package destpicker lists candidate revisions so the user can choose where changes move.
Package destpicker lists candidate revisions so the user can choose where changes move.
components/diffview
Package diffview renders one file's hunks as a scrollable pane, either unified or side by side.
Package diffview renders one file's hunks as a scrollable pane, either unified or side by side.
components/filefinder
Package filefinder is a fuzzy picker modal over a list of items, bound to F.
Package filefinder is a fuzzy picker modal over a list of items, bound to F.
components/filelist
Package filelist renders the changed-file list, either as a one-line summary of the selected file or as a full list, with an inline filter over the paths.
Package filelist renders the changed-file list, either as a one-line summary of the selected file or as a full list, with an inline filter over the paths.
components/help
Package help renders the keybinding overlay.
Package help renders the keybinding overlay.
components/searchmodal
Package searchmodal shows the incremental search prompt and its match counter.
Package searchmodal shows the incremental search prompt and its match counter.
components/splitassign
Package splitassign renders the modal that pairs each split tag with a destination, either an existing revision or a commit to create.
Package splitassign renders the modal that pairs each split tag with a destination, either an existing revision or a commit to create.
components/splitpreview
Package splitpreview renders the read-only summary of a pending multi-way split, one row per tag with its destination and the amount of work assigned to it.
Package splitpreview renders the read-only summary of a pending multi-way split, one row per tag with its destination and the amount of work assigned to it.
components/statusbar
Package statusbar renders the single-line footer: the mode, the diff's source and destination, and the keybinding hints for whatever the user is doing.
Package statusbar renders the single-line footer: the mode, the diff's source and destination, and the keybinding hints for whatever the user is doing.
config
Package config resolves the diff render settings for a session, layering the JJ_DIFF_* environment variables over a set of built-in defaults.
Package config resolves the diff render settings for a session, layering the JJ_DIFF_* environment variables over a set of built-in defaults.
diff
Package diff parses unified diff text into files, hunks, and lines, and turns a user's hunk and line selections back into a patch or into reconstructed files on disk.
Package diff parses unified diff text into files, hunks, and lines, and turns a user's hunk and line selections back into a patch or into reconstructed files on disk.
fuzzy
Package fuzzy scores candidate strings against a subsequence query and ranks them, backing the file and revision pickers.
Package fuzzy scores candidate strings against a subsequence query and ranks them, backing the file and revision pickers.
highlight
Package highlight applies chroma syntax highlighting to diff content, picking a lexer from the file path.
Package highlight applies chroma syntax highlighting to diff content, picking a lexer from the file path.
jj
Package jj shells out to the jj binary for the diff, status, and revision data the UI needs, and carries the one write path that moves selected changes into another revision.
Package jj shells out to the jj binary for the diff, status, and revision data the UI needs, and carries the one write path that moves selected changes into another revision.
model
Package model is the Bubble Tea root: it owns the diff, the selection, and every child component, and routes each key to the handler for the current mode.
Package model is the Bubble Tea root: it owns the diff, the selection, and every child component, and routes each key to the handler for the current mode.
search
Package search finds a literal substring across parsed diffs and tracks the cursor over the hits, including the view position to restore when a search is canceled.
Package search finds a literal substring across parsed diffs and tracks the cursor over the hits, including the view position to restore when a search is canceled.
theme
Package theme holds the Catppuccin palette as package-level colors that every component reads directly.
Package theme holds the Catppuccin palette as package-level colors that every component reads directly.
Package render turns unified diff text into styled terminal lines.
Package render turns unified diff text into styled terminal lines.
tests
integration
Package integration drives internal/jj against a real jj binary in a throwaway repository.
Package integration drives internal/jj against a real jj binary in a throwaway repository.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL