jujutsu.rst (7936B)
1 Introduction to Jujutsu 2 ####################### 3 4 Jujutsu (``jj`` on the command-line) is a modern DVCS, that uses ``git`` 5 repositorie as its storage backend. It borrows extensively from Mercurial, 6 but has many more features. 7 8 .. contents:: Table of Contents 9 10 Links and Resources 11 ------------------- 12 13 - Hope page https://jj-vcs.github.io/jj/latest/ 14 - In-progress tutorial: https://steveklabnik.github.io/jujutsu-tutorial/ 15 - Good introduction and context: https://v5.chriskrycho.com/essays/jj-init/ 16 - Short introduction: 17 https://neugierig.org/software/blog/2024/12/jujutsu.html 18 - Introduction for Mercurial users: 19 https://ahal.ca/blog/2024/jujutsu-mercurial-haven/ 20 - ``:ahal``'s configuration: https://github.com/ahal/dot-files/blob/main/dot-files/jj-config.toml 21 22 Quick Start 23 ----------- 24 25 To get up and running with a fresh checkout, run the following commands 26 (line-separated) after installing ``git`` and ``jj`` (jujutsu): 27 28 :: 29 30 # Create a clone and enter the directory 31 jj git clone --colocate https://github.com/mozilla-firefox/firefox 32 cd firefox # Alternatively, if you have the Git clone already 33 jj git init --colocate 34 35 # Set up jujutsu revset aliases (which will affect e.g. the default `jj log` output) 36 jj config edit --repo 37 <edit> 38 [git] 39 fetch = ["origin"] 40 41 [revset-aliases] 42 "trunk()" = "main@origin" 43 "immutable_heads()" = ''' 44 builtin_immutable_heads() 45 | remote_bookmarks(exact:'autoland') 46 | remote_bookmarks(exact:'beta') 47 | remote_bookmarks(regex:'^esr\d+$') 48 | remote_bookmarks(exact:'release') 49 ''' 50 </edit> 51 52 # Track remote bookmarks (you can do this for the other bookmarks, too) 53 jj bookmark track main@origin autoland@origin beta@origin release@origin 54 55 # Move the working copy commit to bookmarks/central 56 jj new main 57 58 General Tips 59 ------------ 60 61 Changes and Commits 62 ~~~~~~~~~~~~~~~~~~~ 63 64 ``changes`` and ``commits`` are distinct concepts. While in git there’s 65 a one-to-one record of ``changes`` *as* ``commits`` (plus, perhaps, 66 staging), in jujutsu ``commits`` occur fairly frequently (basically any 67 time there’s a change and you run ``jj``, which results in a snapshot). 68 In this sense, ``commits`` can be considered literal snapshot/state 69 commits, whereas ``changes`` are the user-friendly unit-of-work that 70 developers are doing. ``changes`` have hashes that are alphabetic, 71 whereas ``commits`` have hashes which are the same as their git 72 counterparts (sha1, represented as hex characters). 73 74 Thus, a particular ``change`` points to one ``commit`` at a time, 75 however there is a history of ``commits`` recorded for each ``change`` 76 (see ``jj evolog``, for example). You can specify either ``change`` 77 hashes *or* ``commit`` hashes in revsets. 78 79 Co-located Jujutsu and Git 80 ~~~~~~~~~~~~~~~~~~~~~~~~~~ 81 82 A `co-located repository 83 <https://jj-vcs.github.io/jj/latest/git-compatibility/#co-located-jujutsugit-repos>`__ 84 allows running ``jj`` and ``git`` commands in the same repository rather than 85 syncing changes between ``jj`` and ``git`` repositories to switch between the 86 different tools. 87 88 Git commands can be useful because some features are not yet implemented in 89 Jujutsu, such as ``git log`` and ``git rebase`` for `interactions with file 90 renames <https://github.com/jj-vcs/jj/issues/6940>`__ and ``git am`` for 91 `importing patches <https://github.com/jj-vcs/jj/issues/2702>`__. See also 92 :ref:`Transplanting Patches To and From Mercurial Repositories 93 <git-mercurial-transplant>`. 94 95 Firefox Main Tips 96 ----------------- 97 98 Other Useful revset aliases (place in ``.jj/repo/config.toml``) 99 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 100 101 :: 102 103 [revset-aliases] 104 # Get all changes with "Bug 12345" in the subject (can be improved with https://github.com/jj-vcs/jj/issues/5895) 105 'bug_all(x)' = 'mutable() & subject(glob:"Bug *") & subject(x)' 106 # Get head change(s) with "Bug 12345" in the subject 107 'bug(x)' = 'heads(bug_all(x))' 108 # Get root change(s) with "Bug 12345" in the subject 109 'bug_root(x)' = 'roots(bug_all(x))' 110 111 ``moz-phab`` 112 ~~~~~~~~~~~~ 113 114 As of ``moz-phab`` 2.0.0, Jujutsu is officially supported! This applies to both 115 colocated Git/Jujutsu repositories, as well as standalone Jujutsu repositories 116 and workspaces. 117 118 If you are using a colocated repository, you can make ``moz-phab`` use Git 119 instead of Jujutsu by calling it with ``--avoid-jj-vcs``. Note that if you are 120 using ``moz-phab`` with Git like that, most operations require your repo to not 121 be in a detached ``HEAD`` state, which Jujutsu frequently leaves it in. One 122 simple solution is to wrap the ``moz-phab`` command with a script like: 123 124 :: 125 126 #!/bin/sh 127 git checkout -B moz-phab && moz-phab --avoid-jj-vcs "$@" 128 129 You could instead make this a shell alias/function, if preferred. 130 131 ``mach try`` 132 ~~~~~~~~~~~~ 133 134 ``./mach try`` requires a clean working directory to push. When editing 135 a change in Jujutsu, the changes will be moved to the index in Git. 136 Therefore in order to push to try, you must start a new empty change on 137 top of the change you want to push. E.g: 138 139 :: 140 141 $ jj new 142 $ ./mach try ... 143 $ jj prev --edit 144 145 The following alias automates this so you can use ``jj try-push <args>`` 146 instead of ``./mach try <args>`` and it will create/remove a temporary 147 empty change: 148 149 :: 150 151 [aliases] 152 try-push = ["util", "exec", "--", "bash", "-c", """ 153 #!/usr/bin/env bash 154 set -euo pipefail 155 jj new --quiet 156 ./mach try $@ || true 157 jj prev --edit --quiet 158 """, ""] 159 160 See also `Bug 1929372 - [mozversioncontrol] Add unofficial support for 161 Jujutsu 162 repositories <https://bugzilla.mozilla.org/show_bug.cgi?id=1929372>`__ 163 164 ``mach lint`` 165 ~~~~~~~~~~~~~ 166 167 | ``./mach lint`` can be integrated with ``jj fix``. Follow the 168 instructions here: 169 | https://firefox-source-docs.mozilla.org/code-quality/lint/usage.html#jujutsu-integration 170 171 (adding the config to ``jj config edit --repo``) 172 173 The benefit of running ``jj fix`` over ``./mach lint --fix`` directly, 174 is that it will step through all your mutable commits and checkout each 175 file at that revision before running the fixers on it. So you’re 176 guaranteed to get the fix directly in the commit that introduced the 177 issue. 178 179 Rebasing work in progress (and automatically drop changes that have landed) 180 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 181 182 You want something like: 183 184 :: 185 186 jj git fetch && jj rebase --skip-emptied -r 'mutable() & mine()' -d main 187 188 This will: 189 190 1. Pull from the main repo 191 2. Rebase any mutable changesets you’ve made onto the (updated, tracked 192 bookmark) ``main`` changeset, and drop any that become empty (because 193 they have landed) 194 195 Of course you could narrow the scope of what you want to rebase by 196 altering the ``-r`` argument and providing specific revisions, or rebase 197 onto autoland or beta or other bookmarks if you want. 198 199 Dropping/pruning/removing obsolete commits 200 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 201 202 (Note: you may want to look at the `previous 203 tip <#rebasing-work-in-progress-(and-automatically-drop-changes-that-have-landed)>`__!) 204 205 You can use any of: 206 207 :: 208 209 jj abandon x 210 jj abandon x y 211 jj abandon x..z 212 jj abandon x::y 213 214 To abandon individual revision ``x``, both individual revisions ``x`` 215 and ``y``, or the range of commits from ``x`` to ``z``, respectively. 216 217 When you’re dealing with temporary changes that you have not committed 218 (“working directory changes”) this is also an easy way to revert those 219 (a la ``hg revert --no-backup –all``). 220 221 Watchman integration 222 ~~~~~~~~~~~~~~~~~~~~ 223 224 Tired of the frequent Snapshotting… message? Edit your global ``jj`` 225 configuration by doing: 226 227 :: 228 229 jj config edit --user 230 231 and add the following: 232 233 :: 234 235 [core] 236 fsmonitor = "watchman" 237 238 Instead of scanning the file system, ``jj`` will (much like ``hg``\ ’s 239 ``fsmonitor`` extension) use file system events to be notified about 240 file changes, resulting in much shorter operation time, without having 241 to disable the snapshotting mechanism.