docs/sapling-comparison.md
This document attempts to describe how jj is different from Sapling. Sapling is a VCS developed by Meta. It was announced about 3 years after development started on jj. It is a heavily modified fork of Mercurial. Because jj has copied many ideas from Mercurial, there are many similarities between the two tools, such as:
split commands, and
automatically rebasing descendant commits when you amend a commit.Here is a list of some differences between jj and Sapling.
Working copy: When using Sapling (like most VCSs), the user explicitly tells the tool when to create a commit and which files to include. When using jj, the working copy is automatically snapshotted by every command. New files are automatically tracked and deleted files are automatically untracked. This has several advantages:
sl shelve.Conflicts: Like most VCSs, Sapling requires the user to
resolve conflicts before committing. jj lets
you commit conflicts. Note that it's a representation of the
conflict that's committed, not conflict markers (<<<<<<< etc.). This also
has several advantages:
Undo: jj's undo is powered by the operation log, which
records how the repo has changed over time. Sapling has a similar feature
with its MetaLog.
They seem to provide similar functionality, but jj also exposes the log to the
user via jj op log, so you can tell how far back you want to go back.
Sapling has sl debugmetalog, but that seems to show the history of a single
commit, not the whole repo's history. Thanks to jj snapshotting the working
copy, it's possible to undo changes to the working copy. For example, if
you jj undo a jj commit, jj diff will show the same changes as
before jj commit, but if you sl undo a sl commit, the working copy will
be clean.
Git interop: Sapling supports cloning, pushing, and pulling from a remote
Git repo. jj also does, and it also supports sharing a working copy with a Git
repo, so you can use jj and git interchangeably in the same repo.
Polish: Sapling is more polished and feature-complete. Sapling has very nice built-in web UI called Interactive Smartlog, which lets you drag and drop commits to rebase them, among other things.
Forge workflow: Sapling has sl pr submit --stack, which lets you
push a stack of commits as separate GitHub PRs, including setting the base
branch. It only supports GitHub. jj doesn't have any direct integration with
GitHub or any other forge. However, it has jj git push --change for
automatically creating branches for specified commits. You have to specify
each commit you want to create a branch for by using
jj git push --change X --change Y ..., and you have to manually set up any
base branches in GitHub's UI (or GitLab's or ...). On subsequent pushes, you
can update all at once by specifying something like jj git push -r main..@
(to push all branches on the current stack of commits from where it forked
from main).