jj-mode provides a magit-inspired interface for Jujutsu, offering an efficient way to interact with JJ repositories from within Emacs.
- Magit-style log viewer with collapsible sections and syntax highlighting
- Interactive rebase with visual source/destination selection via transients
- Bookmark management with create, abandon, forget, track, and tug operations
- Commit and describe with dedicated message buffers and window management
- Diff viewing with file and hunk-level navigation
- Context-sensitive actions via DWIM (Do What I Mean) Enter key behavior
- Git integration with push/fetch operations and configurable options
- Built-in conflict resolution using Emacs ediff and smerge-mode
- Emacs 26.1 or later
- Jujutsu (jj) installed and in PATH
- magit (for section management and UI components)
- transient (usually bundled with magit)
(package! jj-mode :recipe (:host github :repo "bolivier/jj-mode.el"))(use-package jj-mode
:straight (:host github :repo "bolivier/jj-mode.el"))(use-package jj-mode
:vc (:url "https://github.com/bolivier/jj-mode.el"))Clone this repository and add it to your load path:
(add-to-list 'load-path "/path/to/jj-mode")
(require 'jj-mode)Start with M-x jj-log to open the main interface. Each project gets its own
buffer (*jj-log:project-name*).
n/p- Navigate between sectionsRET- Context-sensitive action (edit changeset, jump to file/line in diffs).- Jump to current changeset (@)TAB- Toggle section folding
g- Refresh logc- Commit (opens message buffer)d- Describe changeset at point (opens message buffer)e- Edit changeset (jj edit)u- Undo last operations- SquashN- New changeset here
r- Rebase transient menus- Set rebase sourced- Toggle rebase destinationr- Execute rebasec- Clear selections
b- Bookmark transient menuc- Create bookmarka- Abandon bookmarkf- Forget bookmarkt- Track remote bookmarkT- Tug (jj tug)
G- Git operations transient-n- Toggle --allow-new flag-b- Set bookmark to pushp- Pushf- Fetch
E- Edit conflicts with ediffM- Edit conflicts with smerge-mode
When editing commit/describe messages:
C-c C-c- Finish and executeC-c C-k- Cancel
M-x jj-log- Open JJ interface- Navigate to desired changeset with
j/k c- Commit current changes- Edit message,
C-c C-cto finish r- Open rebase menu, select source withs, destinations withd, execute withrb- Manage bookmarks as neededGp- Push to remote
;; Customize jj executable path if needed
(setq jj-executable "/path/to/jj")Issues and pull requests welcome! This project aims to provide a solid JJ interface while maintaining magit-like usability patterns.