Jujutsu VCS

Jujutsu VCS
The Jujutsu VCS Logo by J. Jennings

No clever opener here. If you use Git, you need to try jj. It gives you a faster, more intuitive, and more productive workflow. Without sacrificing anything Git offers. At the bottom of this posting, i share some links to get you started.

You don't believe me that jj is worth a look, but you're still curious?

I won't replicate the documentation or the sources linked at the very bottom, but will instead share my very personal impressions and notes. These impressions are probably not the things you would notice yourself when diving into Jujutsu VCS, but at the same time, they might be interesting enough to give you a sense of what jj is — and what it isn’t.

Built on Git

Wait what? Yes. Jujutsu's best trick is that you can use it today on your personal machine with any Git repository you have access to.

  • You can use jj with its Git backend BUT without .git at all locally with jj git clone or jj git init.
  • You can use jj with its Git backend and .git locally with --colocate.

One of the best decisions Linus Torvalds made when he started with Git was that he didn't want to write a version control system, but rather a kind of "filesystem for versions of source code archives" (which he called "plumbing"), and he actually expected someone else to write the version control part on top of that — the so-called "porcelain". That's still the case today. Jujutsu is, in a way, this new, shiny porcelain.

The exciting and interesting things

jj is literally at your fingertips — just double-tap j. It’s snappier than git, hg, bk, or anything else. That alone might be the best part. Or is it?

  • Commits are called revisions. There are also changes, which are automatically added to your current revision as you work.
  • Jujutsu is more lightweight, high-level, automated and concise than git. Take a look at what jj does not do compared to git.
  • The CLI feels polished and reminds me of mercurial (hg) — avoiding many of Git’s long-standing UX issues. The author of jj Martin von Zweigbergk worked an mercurial before and now works at Google. Though jj is not officially a Google project.
  • Thinking of Google and their big monorepo sourcecode base, jj is able to use scalable storage backends like S3, Dropbox, rsync, and more, because it is lock-free, see: Concurrency backends.
  • Jujutsu feels like a "branchless Git", which is not a new idea. You work with changes (like git commit), but only name them if and when you want — or when you need to interact with a git remote, because vanilla git does force you to name everything. That means in practice:
    • Fewer concepts: no staging/index, no detached HEAD.
    • Graph editing is first-class: reordering, rewriting, and cleaning up is seamless.
    • Rebasing happens automatically and doesn’t block you.
    • Conflicts don’t stop you: you can continue to add/remove changes and resolve conflicts later.
  • Clean and consistent CLI: Most commands work on the repository’s internal data structures, not the working copy.
    • Do a jj help -k config and read.
    • Fast operations that don’t block your flow or confuse your IDE and LSP servers.
    • Snapshots are done automatically after nearly every command.
    • Creating revisions is flexible and natural:
      • jj describe -m "<message>" && jj new is intuitive and powerful.
      • No strict commit workflow like in Git.
      • No need to name everything.
      • No need to jump between unwieldly branches or manage worktrees.
    • Browse and jump through states with jj op log and resume work from any point.
    • Incredibly powerful and flexible jj undo system.
    • jj rebase and jj new <rev> <rev>... -m "merge" always succeed — even when conflicts are created.
    • jj new can optionally keep your current position with --no-edit.
    • Powerful Revset language for querying revisions:
      • Use symbols (@ for working copy), operators (|, &, ::), and functions (root(), mine(), heads(), etc.).
      • Full docs here.

Pitfalls

There are some pitfalls i encountered. I want to share them hoping others can avoid them.

Breaking changes and upgrades: Jujutsu has not reached version 1.0 yet. That means breaking changes can and do occur frequently.
Check the changelog before upgrading — a new version is released roughly every month.

Documentation and AI prompts: Much of the unofficial documentation (and what AI tools like ChatGPT might tell you) about Jujutsu is outdated. Several subcommands have been renamed or removed, and the recommended workflows have evolved. Anything from before late 2024 is likely deprecated or misleading. Stick to the official documentation and the GitHub repository for accurate, up-to-date information.

Fresh repositories: If you're starting with a clean repository with the intention to share it later on via Github or another git forge, always run git init first to create an initial branch, working copy, and HEAD. Only then run: jj git init --colocate . This ensures that Jujutsu colocates with Git properly, sharing the same repository state. Skipping this step makes it unnecessarily hard to create a primary branch or HEAD, or to use bookmarks that track Git branches.

Jujutsu Change ID vs. Git Commit ID:

  • Change ID: A stable identifier used internally by Jujutsu to track logical changes. These don't change and are used in day-to-day local development.
  • Commit ID: The actual Git commit ID, which can change when rewriting history or rebasing. Required for interoperability with Git remotes.

For local work, it’s fine to think in terms of change IDs. When collaborating via GitHub, GitLab, Forgejo, or any Git-based remote, you’ll need to deal with Commit IDs and bookmarks/branches.

Understanding --from and --to in Diffs: When using jj diff --from <rev> --to <rev>, think in terms of: "What changes would need to be applied, starting after --from, to arrive at the state in --to?" In my personal opinion, this model is often more intuitive than how Git handles diffs.

Revisions vs. Commits: In Jujutsu, the concept of a revision is broader than that of a git commit.

  • A git commit is a specific snapshot in history.
  • A jj revision can be dynamic, such as your current working change which hasn't been committed yet. For example:
    • jj bookmark move works on revisions.
    • jj bookmark set works on commits.

Editing remote bookmarks (called branches on git remotes): When you jj edit a bookmark that was created via git fetch, you’ll start on a new, empty, active change, similar to jj new . This is intentional: You're expected to make changes and then rebase onto the remote state when ready. This is a bit like the concept of non-linear editing in media manipulation software.

Git submodules: Git submodules are not supported. Jujutsu simply ignores them. You'll need to manage submodules manually using Git commands like git submodule init and git submodule update. The Jujutsu team is working on a better alternative to Git submodules, which is why compatibility is taking longer.

Git LFS: LFS is not supported. Unlike submodules, Jujutsu is effectively unusable in repositories that rely on Git LFS. This is currently a hard blocker for using jj in such projects.

More information

Here are some valuable resources on Jujutsu (jj):

  • Jujutsu on the web: The documentation. Best source to read through the concepts, architecture and design.
  • Scott Chacon on Jujutsu: A Jujutsu hands-on video with Scott Chacon and Caleb. Scott is a co-founder of GitHub and GitButler, wrote the arguable most famous git book. A nice way to get motivated.
  • Steve Klabnik's Jujutsu Tutorial: A comprehensive guide for beginners to understand and use Jujutsu effectively by walking through it. Good way to get started.
  • Introduction to the Jujutsu VCS by Kuba Martin: An insightful article from early 2025 providing a fresh perspective on Jujutsu's capabilities and usage patterns. Good way to better understand in what aspects git and jj differ and where the are similar.
  • The Jujutsu VCS logo license for the logo used in this article.