Bug 1968219 - Import initial jujutsu docs in-tree. r=afranchuk
Differential Revision: https://phabricator.services.mozilla.com/D250920
This commit is contained in:
committed by
padenot@mozilla.com
parent
e2ac38c2a8
commit
5829822095
@@ -16,6 +16,7 @@ development process and source code documentation.
|
||||
levelling-up
|
||||
how_to_submit_a_patch
|
||||
data-review
|
||||
jujutsu
|
||||
|
||||
|
||||
.. toctree::
|
||||
|
||||
228
docs/contributing/jujutsu.rst
Normal file
228
docs/contributing/jujutsu.rst
Normal file
@@ -0,0 +1,228 @@
|
||||
Introduction to Jujutsu
|
||||
#######################
|
||||
|
||||
Jujutsu (``jj`` on the command-line) is a modern DVCS, that uses ``git``
|
||||
repositorie as its storage backend. It borrows extensively from Mercurial,
|
||||
but has many more features.
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
Links and Resources
|
||||
-------------------
|
||||
|
||||
- Hope page https://jj-vcs.github.io/jj/latest/
|
||||
- In-progress tutorial: https://steveklabnik.github.io/jujutsu-tutorial/
|
||||
- Good introduction and context: https://v5.chriskrycho.com/essays/jj-init/
|
||||
- Short introduction:
|
||||
https://neugierig.org/software/blog/2024/12/jujutsu.html
|
||||
- Introduction for Mercurial users:
|
||||
https://ahal.ca/blog/2024/jujutsu-mercurial-haven/
|
||||
- ``:ahal``'s configuration: https://github.com/ahal/dot-files/blob/main/dot-files/jj-config.toml
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
|
||||
To get up and running with a fresh checkout, run the following commands
|
||||
(line-separated) after installing ``git`` and ``jj`` (jujutsu):
|
||||
|
||||
::
|
||||
|
||||
# Create a clone and enter the directory
|
||||
jj git clone --colocate https://github.com/mozilla-firefox/firefox
|
||||
cd firefox # Alternatively, if you have the Git clone already
|
||||
jj git init --colocate
|
||||
|
||||
# Set up jujutsu revset aliases (which will affect e.g. the default `jj log` output)
|
||||
jj config edit --repo
|
||||
<edit>
|
||||
[git]
|
||||
fetch = ["origin"]
|
||||
|
||||
[revset-aliases]
|
||||
"trunk()" = "main@origin"
|
||||
"immutable_heads()" = '''
|
||||
builtin_immutable_heads()
|
||||
| remote_bookmarks('autoland')
|
||||
| remote_bookmarks('beta')
|
||||
| remote_bookmarks('esr')
|
||||
| remote_bookmarks('release')
|
||||
'''
|
||||
</edit>
|
||||
|
||||
# Track remote bookmarks (you can do this for the other bookmarks, too)
|
||||
jj bookmark track main@origin autoland@origin beta@origin release@origin
|
||||
|
||||
# Move the working copy commit to bookmarks/central
|
||||
jj new main
|
||||
|
||||
General Tips
|
||||
------------
|
||||
|
||||
Changes and Commits
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``changes`` and ``commits`` are distinct concepts. While in git there’s
|
||||
a one-to-one record of ``changes`` *as* ``commits`` (plus, perhaps,
|
||||
staging), in jujutsu ``commits`` occur fairly frequently (basically any
|
||||
time there’s a change and you run ``jj``, which results in a snapshot).
|
||||
In this sense, ``commits`` can be considered literal snapshot/state
|
||||
commits, whereas ``changes`` are the user-friendly unit-of-work that
|
||||
developers are doing. ``changes`` have hashes that are alphabetic,
|
||||
whereas ``commits`` have hashes which are the same as their git
|
||||
counterparts (sha1, represented as hex characters).
|
||||
|
||||
Thus, a particular ``change`` points to one ``commit`` at a time,
|
||||
however there is a history of ``commits`` recorded for each ``change``
|
||||
(see ``jj evolog``, for example). You can specify either ``change``
|
||||
hashes *or* ``commit`` hashes in revsets.
|
||||
|
||||
Firefox Main Tips
|
||||
-----------------
|
||||
|
||||
Other Useful revset aliases (place in ``.jj/repo/config.toml``)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
[revset-aliases]
|
||||
# Get all changes with "Bug 12345" in the subject (can be improved with https://github.com/jj-vcs/jj/issues/5895)
|
||||
'bug_all(x)' = 'mutable() & subject(glob:"Bug *") & subject(x)'
|
||||
# Get head change(s) with "Bug 12345" in the subject
|
||||
'bug(x)' = 'heads(bug_all(x))'
|
||||
# Get root change(s) with "Bug 12345" in the subject
|
||||
'bug_root(x)' = 'roots(bug_all(x))'
|
||||
|
||||
``moz-phab``
|
||||
~~~~~~~~~~~~
|
||||
|
||||
WIP support for Jujutsu in ``moz-phab`` is being developed at
|
||||
```erichdongubler-mozilla/review``\ #1 <https://github.com/erichdongubler-mozilla/review/pull/1>`__.
|
||||
You can install this via:
|
||||
|
||||
::
|
||||
|
||||
pip install MozPhab@git+https://github.com/erichdongubler-mozilla/review@refs/pull/1/head
|
||||
|
||||
If you need to fall back to using Git with vanilla ``moz-phab``, most
|
||||
operations require you to not be in a detached ``HEAD`` state. However,
|
||||
Jujutsu frequently leaves it in one. One simple solution is to wrap the
|
||||
``moz-phab`` command with a script like:
|
||||
|
||||
::
|
||||
|
||||
#!/bin/sh
|
||||
git checkout -B moz-phab && moz-phab "$@"
|
||||
|
||||
You could instead make this a shell alias/function, if preferred.
|
||||
|
||||
``mach try``
|
||||
~~~~~~~~~~~~
|
||||
|
||||
``./mach try`` requires a clean working directory to push. When editing
|
||||
a change in Jujutsu, the changes will be moved to the index in Git.
|
||||
Therefore in order to push to try, you must start a new empty change on
|
||||
top of the change you want to push. E.g:
|
||||
|
||||
::
|
||||
|
||||
$ jj new
|
||||
$ ./mach try ...
|
||||
$ jj prev --edit
|
||||
|
||||
The following alias automates this so you can use ``jj try-push <args>``
|
||||
instead of ``./mach try <args>`` and it will create/remove a temporary
|
||||
empty change:
|
||||
|
||||
::
|
||||
|
||||
[aliases]
|
||||
try-push = ["util", "exec", "--", "bash", "-c", """
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
jj new --quiet
|
||||
./mach try $@ || true
|
||||
jj prev --edit --quiet
|
||||
""", ""]
|
||||
|
||||
See also `Bug 1929372 - [mozversioncontrol] Add unofficial support for
|
||||
Jujutsu
|
||||
repositories <https://bugzilla.mozilla.org/show_bug.cgi?id=1929372>`__
|
||||
|
||||
``mach lint``
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
| ``./mach lint`` can be integrated with ``jj fix``. Follow the
|
||||
instructions here:
|
||||
| https://firefox-source-docs.mozilla.org/code-quality/lint/usage.html#jujutsu-integration
|
||||
|
||||
(adding the config to ``jj config edit --repo``)
|
||||
|
||||
The benefit of running ``jj fix`` over ``./mach lint --fix`` directly,
|
||||
is that it will step through all your mutable commits and checkout each
|
||||
file at that revision before running the fixers on it. So you’re
|
||||
guaranteed to get the fix directly in the commit that introduced the
|
||||
issue.
|
||||
|
||||
Rebasing work in progress (and automatically drop changes that have landed)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You want something like:
|
||||
|
||||
::
|
||||
|
||||
jj git fetch && jj rebase --skip-emptied -r 'mutable() & mine()' -d main
|
||||
|
||||
This will:
|
||||
|
||||
1. Pull from the main repo
|
||||
2. Rebase any mutable changesets you’ve made onto the (updated, tracked
|
||||
bookmark) ``main`` changeset, and drop any that become empty (because
|
||||
they have landed)
|
||||
|
||||
Of course you could narrow the scope of what you want to rebase by
|
||||
altering the ``-r`` argument and providing specific revisions, or rebase
|
||||
onto autoland or beta or other bookmarks if you want.
|
||||
|
||||
Dropping/pruning/removing obsolete commits
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
(Note: you may want to look at the `previous
|
||||
tip <#rebasing-work-in-progress-(and-automatically-drop-changes-that-have-landed)>`__!)
|
||||
|
||||
You can use any of:
|
||||
|
||||
::
|
||||
|
||||
jj abandon x
|
||||
jj abandon x y
|
||||
jj abandon x..z
|
||||
jj abandon x::y
|
||||
|
||||
To abandon individual revision ``x``, both individual revisions ``x``
|
||||
and ``y``, or the range of commits from ``x`` to ``z``, respectively.
|
||||
|
||||
When you’re dealing with temporary changes that you have not committed
|
||||
(“working directory changes”) this is also an easy way to revert those
|
||||
(a la ``hg revert --no-backup –all``).
|
||||
|
||||
Watchman integration
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Tired of the frequent Snapshotting… message? Edit your global ``jj``
|
||||
configuration by doing:
|
||||
|
||||
::
|
||||
|
||||
jj config edit --user
|
||||
|
||||
and add the following:
|
||||
|
||||
::
|
||||
|
||||
[core]
|
||||
fsmonitor = "watchman"
|
||||
|
||||
Instead of scanning the file system, ``jj`` will (much like ``hg``\ ’s
|
||||
``fsmonitor`` extension) use file system events to be notified about
|
||||
file changes, resulting in much shorter operation time, without having
|
||||
to disable the snapshotting mechanism.
|
||||
Reference in New Issue
Block a user