Skip to content

Commit

Permalink
docs: add doc comparing jj to Sapling (#1708)
Browse files Browse the repository at this point in the history
  • Loading branch information
martinvonz committed Jun 21, 2023
1 parent 038b64d commit dcf4bbc
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 1 deletion.
3 changes: 2 additions & 1 deletion docs/related-work.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Similar tools:
* [Sapling](https://sapling-scm.com/): A heavily modified fork of
[Mercurial](https://www.mercurial-scm.org/) developed and used at Meta. It
is compatible with Git, has undo functionality, and
[a graphical interface](https://sapling-scm.com/docs/addons/isl).
[a graphical interface](https://sapling-scm.com/docs/addons/isl).
See [how it is different from Jujutsu](sapling-comparison.md).
* [GitUp](https://gitup.co/): A Mac-only GUI for Git. Like Jujutsu, supports
undo and restoring the repo to an earlier snapshot. Backed by its
[GitUpKit library](https://github.com/git-up/GitUp#gitupkit).
Expand Down
73 changes: 73 additions & 0 deletions docs/sapling-comparison.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Comparison with Sapling

## Introduction

This document attempts to describe how jj is different
from [Sapling](sapling-scm.com). Sapling is a VCS developed by Meta. It is a
heavily modified fork of [Mercurial](https://www.mercurial-scm.org/). Because
jj has copied many ideas from Mercurial, there are many similarities between the
two tools, such as:

* A user-friendly CLI
* A "[revset](revsets.md)" language for selecting revisions
* Good support for working with stacked commits, including tracking "anonymous
heads" (no "detached HEAD" state like in Git) and `split` commands, and
automatically rebasing descendant commits when you amend a commit.
* Flexible customization of output using [templates](templates.md)

## Differences

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](working-copy.md). New files
are automatically tracked and deleted files are automatically untracked. This
has several advantages:
* The working copy is effectively backed up every time you run a command.
* No commands fail because you have changes in the working copy ("abort: 1
conflicting file changes: ..."). No need for `sl shelve`.
* Simpler and more consistent CLI because the working copy is treated like
any other commit.
* **Conflicts:** Like most VCSs, Sapling requires the user to
resolve conflicts before committing. jj lets
you [commit conflicts](conflicts.md). Note that it's a representation of the
conflict that's committed, not conflict markers (`<<<<<<<` etc.). This also
has several advantages:
* Merge conflicts won't prevent you from checking out another commit.
* You can resolve the conflicts when you feel like it.
* Rebasing descendants always succeeds. Like jj, Sapling automatically
rebases, but it will fail if there are conflicts.
* Merge commits can be rebased correctly (Sapling sometimes fails).
* You can rebase conflicts and conflict resolutions.
* **Undo:** jj's undo is powered by [the operation log](operation-log.md), which
records how the repo has changed over time. Sapling has a similar feature
with its [MetaLog](https://sapling-scm.com/docs/internals/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 much more polished and feature-complete. For example,
jj has no `blame/annotate` or `bisect` commands, and also no copy/rename
support. Sapling also has very nice web UI
called [Interactive Smartlog](https://sapling-scm.com/docs/addons/isl), 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`).

0 comments on commit dcf4bbc

Please sign in to comment.