just playing with tangled
at gvimdiff 495 lines 19 kB view raw view rendered
1# How to Contribute 2 3 4## Policies 5 6We'd love to accept your patches and contributions to this project. There are 7just a few small guidelines you need to follow. 8 9### Contributor License Agreement 10 11Contributions to this project must be accompanied by a Contributor License 12Agreement. You (or your employer) retain the copyright to your contribution; 13this simply gives us permission to use and redistribute your contributions as 14part of the project. Head over to <https://cla.developers.google.com/> to see 15your current agreements on file or to sign a new one. 16 17You generally only need to submit a CLA once, so if you've already submitted one 18(even if it was for a different project), you probably don't need to do it 19again. 20 21### Commit guidelines 22 23Unlike many GitHub projects (but like many VCS projects), we care more about the 24contents of commits than about the contents of PRs. We review each commit 25separately, and we don't squash-merge the PR (so please manually squash any 26fixup commits before sending for review). 27 28Each commit should ideally do one thing. For example, if you need to refactor a 29function in order to add a new feature cleanly, put the refactoring in one 30commit and the new feature in a different commit. If the refactoring itself 31consists of many parts, try to separate out those into separate commits. You can 32use `jj split` to do it if you didn't realize ahead of time how it should be 33split up. Include tests and documentation in the same commit as the code they 34test and document. 35 36The commit message should describe the changes in the commit; 37the PR description can even be empty, but feel free to include a personal 38message. We start the commit message with `<topic>: ` and don't use 39[conventional commits](https://www.conventionalcommits.org/en/v1.0.0/). This means if 40you modified a command in the CLI, use its name as the topic, e.g. 41`next/prev: <your-modification>` or `conflicts: <your-modification>`. We don't 42currently have a specific guidelines on what to write in the topic field, but 43the reviewers will help you provide a topic if you have difficulties choosing 44it. [How to Write a Git Commit Message](https://cbea.ms/git-commit/) is a good 45guide if you're new to writing good commit messages. We are not particularly 46strict about the style, but please do explain the reason for the change unless 47it's obvious. 48 49### Code reviews 50 51All submissions, including submissions by project members, require review. We 52use GitHub pull requests for this purpose. Consult 53[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 54information on using pull requests. 55 56When you address comments on a PR, don't make the changes in a commit on top (as 57is typical on GitHub). Instead, please make the changes in the appropriate 58commit. You can do that by creating a new commit on top of the initial commit 59 (`jj new <commit>`) and then squash in the changes when you're done (`jj squash`). 60`jj git push` 61will automatically force-push the bookmark. 62 63When your first PR has been approved, we typically invite you to the 64`jj-vcs/contributors` team to give you contributor access, 65so you can address any remaining minor comments and then merge the PR yourself 66when you're ready. If you realize that some comments require non-trivial 67changes, please ask your reviewer to take another look. 68 69If your employer pays anyone (not necessarily you) to contribute to Jujutsu, 70please make sure your GitHub username is [recorded](paid_contributors.md). 71To avoid conflicts of interest, please don't merge a PR that has only been 72approved by someone from the same organization. Similarly, as a reviewer, there 73is no need to approve your coworkers' PRs, since the author should await an 74approval from someone else anyway. It is of course still appreciated if you 75review and comment on their PRs. Also, if the PR seems completely unrelated to 76your company's interests, do feel free to approve it. 77 78### Community Guidelines 79 80This project follows [Google's Open Source Community 81Guidelines](https://opensource.google/conduct/). 82 83## Contributing large patches 84 85Before sending a PR for a large change which designs/redesigns or reworks an 86existing component, we require an architecture review from multiple 87stakeholders, which we do with [Design Docs](design_docs.md), see the 88[process here](design_docs.md#process). 89 90## Contributing to the documentation 91 92We appreciate [bug 93reports](https://github.com/jj-vcs/jj/issues/new?template=bug_report.md) 94about any problems, however small, lurking in [our documentation 95website](https://jj-vcs.github.io/jj/prerelease) or in the `jj help 96<command>` docs. If a part of the bug report template does not apply, you can 97just delete it. 98 99Before reporting a problem with the documentation website, we'd appreciate it if 100you could check that the problem still exists in the "prerelease" version of the 101documentation (as opposed to the docs for one of the released versions of `jj`). 102You can use the version switcher in the top-left of the website to do so. 103 104If you are willing to make a PR fixing a documentation problem, even better! 105 106The documentation website sources are Markdown files located in the [`docs/` 107directory](https://github.com/jj-vcs/jj/tree/main/docs). You do not need to 108know Rust to work with them. See below for [instructions on how to preview the 109HTML docs](#previewing-the-html-documentation) as you edit the Markdown files. 110Doing so is optional, but recommended. 111 112The `jj help` docs are sourced from the "docstring" comments inside the Rust 113sources, currently from the [`cli/src/commands` 114directory](https://github.com/jj-vcs/jj/tree/main/cli/src/commands). Working 115on them requires setting up a Rust development environment, as described 116below, and may occasionally require adjusting a test. 117 118 119## Learning Rust 120 121In addition to the [Rust Book](https://doc.rust-lang.org/book/) and the other 122excellent resources at <https://www.rust-lang.org/learn>, we recommend the 123["Comprehensive Rust" mini-course](https://google.github.io/comprehensive-rust/) 124for an overview, especially if you are familiar with C++. 125 126## Setting up a development environment 127 128To develop `jj`, the mandatory steps are simply 129to [install Rust](https://www.rust-lang.org/tools/install) (the default 130installer options are fine), clone the repository, and use `cargo build` 131, `cargo fmt`, 132`cargo clippy --workspace --all-targets`, and 133`cargo test --workspace`. If you are preparing a PR, there are some additional 134recommended steps. 135 136### Summary 137 138One-time setup: 139 140 rustup toolchain add nightly # wanted for 'rustfmt' 141 rustup toolchain add 1.84 # also specified in Cargo.toml 142 cargo install --locked bacon 143 cargo install --locked cargo-insta 144 cargo install --locked cargo-nextest 145 146During development (adapt according to your preference): 147 148 bacon clippy-all 149 cargo +nightly fmt # Occasionally 150 cargo nextest run --workspace # Occasionally 151 cargo insta test --workspace --test-runner nextest # Occasionally 152 153!!! warning 154 155 Build artifacts from debug builds and especially from repeated 156 invocations of `cargo test` can quickly take up 10s of GB of disk space. 157 Cargo will happily use up your entire hard drive. If this happens, run 158 `cargo clean`. 159 160### Explanation 161 162These are listed roughly in order of decreasing importance. 163 1641. Nearly any change to `jj`'s CLI will require writing or updating snapshot 165 tests that use the [`insta`](https://insta.rs/) crate. To make this 166 convenient, install the `cargo-insta` binary. 167 Use `cargo insta test --workspace` to run tests, 168 and `cargo insta review --workspace` to update the snapshot tests. 169 The `--workspace` flag is needed to run the tests on all crates; by default, 170 only the crate in the current directory is tested. 171 1722. GitHub CI checks require that the code is formatted with the *nightly* 173 version of `rustfmt`. To do this on your computer, install the nightly 174 toolchain and use `cargo +nightly fmt`. 175 1763. Your code will be rejected if it cannot be compiled with the minimal 177 supported version of Rust ("MSRV"). Currently, `jj` follows a rather 178 casual MSRV policy: "The current `rustc` stable version, minus one." 179 As of this writing, that version is **1.84.0**. 180 1814. Your code needs to pass `cargo clippy`. You can also 182 use `cargo +nightly clippy` if you wish to see more warnings. 183 1845. You may also want to install and use [`bacon`](https://dystroy.org/bacon/), 185 to automatically build, check, and / or run tests. 186 1876. To run tests more quickly, use `cargo nextest run --workspace`. To 188 use `nextest` with `insta`, use `cargo insta test --workspace 189 --test-runner nextest`. 190 191 On Linux, you may be able to speed up `nextest` even further by using 192 the `mold` linker, as explained below. 193 194 195### Configuring `jj fix` to run `rustfmt` 196 197Run this in the jj repo: 198 199```shell 200jj config set --repo fix.tools.rustfmt '{ command = ["rustfmt", "+nightly"], patterns = ["glob:**/*.rs"] }' 201``` 202 203### Using `mold` for faster tests on Linux 204 205On a machine with a multi-core CPU, one way to speed up 206`cargo nextest` on Linux is to use the multi-threaded [`mold` 207linker](https://github.com/rui314/mold). This linker may help 208if, currently, your CPU is underused while Rust is linking test 209binaries. Before proceeding with `mold`, you can check whether this is 210an issue worth solving using a system monitoring tool such as `htop`. 211 212`mold` is packaged for many distributions. On Debian, for example, 213`sudo apt install mold` should just work. 214 215A simple way to use `mold` is via the `-run` option, e.g.: 216 217```shell 218mold -run cargo insta test --workspace --test-runner nextest 219``` 220 221There will be no indication that a different linker is used, except for 222higher CPU usage while linking and, hopefully, faster completion. You 223can verify that `mold` was indeed used by running 224`readelf -p .comment target/debug/jj`. 225 226There are also ways of having Rust use `mold` by default, see the ["How 227to use" instructions](https://github.com/rui314/mold#how-to-use). 228 229On recent versions of MacOS, the default linker Rust uses is already 230multi-threaded. It should use all the CPU cores without any configuration. 231 232### Editor setup 233 234#### Visual Studio Code 235 236We recommend at least these settings: 237 238```js 239{ 240 "files.insertFinalNewline": true, 241 "files.trimTrailingWhitespace": true, 242 "[rust]": { 243 "files.trimTrailingWhitespace": false 244 } 245} 246``` 247 248#### Zed 249 250```js 251// .zed/settings.json 252{ 253 "ensure_final_newline_on_save": true, 254 "remove_trailing_whitespace_on_save": true, 255 256 "languages": { 257 // We don't use a formatter for Markdown files, so format_on_save would just 258 // mess with others' docs 259 "Markdown": { "format_on_save": "off" } 260 "Rust": { 261 "format_on_save": "on", 262 // Avoid removing trailing spaces within multi-line string literals 263 "remove_trailing_whitespace_on_save": false 264 } 265 }, 266 267 "lsp": { 268 "rust-analyzer": { 269 "initialization_options": { 270 // If you are working on docs and don't need `cargo check`, uncomment 271 // this option: 272 // 273 // "checkOnSave": false, 274 275 // Use nightly `rustfmt`, equivalent to `cargo +nightly fmt` 276 "rustfmt": { "extraArgs": ["+nightly"] } 277 } 278 } 279 } 280} 281``` 282 283## Previewing the HTML documentation 284 285The documentation for `jj` is automatically published online at 286<https://jj-vcs.github.io/jj/>. 287 288When editing documentation, you should check your changes locally — especially 289if you are adding a new page, or doing a major rewrite. 290 291### Install `uv` 292 293The only thing you need is [`uv`][uv] (version 0.5.1 or newer). 294 295`uv` is a Python project manager written in Rust. It will fetch the right Python 296version and the dependencies needed to build the docs. Install it like so: 297 298[uv]: https://docs.astral.sh/uv/ 299 300=== "macOS/Linux" 301 302 ``` { .shell .copy } 303 curl -LsSf https://astral.sh/uv/install.sh | sh 304 ``` 305 306 !!! note 307 If you don't have `~/.local/bin` in your `PATH`, the installer will 308 modify your shell profile. To avoid it: 309 310 ``` { .shell .copy } 311 curl -LsSf https://astral.sh/uv/install.sh | env INSTALLER_NO_MODIFY_PATH=1 sh 312 ``` 313 314=== "Windows" 315 316 ``` { .shell .copy } 317 powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" 318 ``` 319 320=== "Homebrew" 321 322 ``` { .shell .copy } 323 brew install uv 324 ``` 325 326=== "Cargo" 327 328 ``` { .shell .copy } 329 # This might take a while 330 cargo install --git https://github.com/astral-sh/uv uv 331 ``` 332 333=== "Other options" 334 335 * Directly download the binaries from GitHub: [uv releases](https://github.com/astral-sh/uv/releases). 336 * Even more options: [Installing uv](https://docs.astral.sh/uv/getting-started/installation/). 337 338### Build the docs 339 340To build the docs, run from the root of the `jj` repository: 341 342``` { .shell .copy } 343uv run mkdocs serve 344``` 345 346Open <http://127.0.0.1:8000> in your browser to see the docs. 347 348As you edit the `.md` files in `docs/`, the website should be rebuilt and 349reloaded in your browser automatically. 350 351!!! note "If the docs are not updating" 352 Check the terminal from which you ran `uv run mkdocs serve` for any build 353 errors or warnings. Warnings about `"GET /versions.json HTTP/1.1" code 404` 354 are expected and harmless. 355 356## Building the entire website 357 358!!! tip 359 Building the entire website is not usually necessary. If you are editing 360 documentation, the previous section is enough. 361 362 These instructions are relevant if you are working on the versioning of the 363 documentation that we currently do with `mike`. 364 365The full `jj` website includes the documentation for several `jj` versions 366(`prerelease`, latest release, and the older releases). The top-level 367URL <https://jj-vcs.github.io/jj> redirects to 368<https://jj-vcs.github.io/jj/latest>, which in turn redirects to 369the docs for the last stable version. 370 371The different versions of documentation are managed and deployed with 372[`mike`](https://github.com/jimporter/mike), which can be run with 373`uv run mike`. 374 375On a POSIX system or WSL, one way to build the entire website is as follows (on 376Windows, you'll need to understand and adapt the shell script): 377 3781. Check out `jj` as a co-located `jj + git` repository (`jj clone --colocate`), 379cloned from your fork of `jj` (e.g. `github.com/jjfan/jj`). You can also use a 380pure Git repo if you prefer. 381 3822. Make sure `github.com/jjfan/jj` includes the `gh-pages` bookmark of the jj repo 383and run `git fetch origin gh-pages`. 384 3853. Go to the GitHub repository settings, enable GitHub Pages, and configure them 386to use the `gh-pages` bookmark (this is usually the default). 387 3884. Install `uv` as explained in [Previewing the HTML 389documentation](#previewing-the-html-documentation), and run the same `sh` script 390that is used in GitHub CI (details below): 391 392 ```shell 393 .github/scripts/docs-build-deploy prerelease main --push 394 ``` 395 396 This should build the version of the docs from the current commit, 397 deploy it as a new commit to the `gh-pages` bookmark, 398 and push the `gh-pages` bookmark to the origin. 399 4005. Now, you should be able to see the full website, including your latest changes 401to the `prerelease` version, at `https://jjfan.github.io/jj/prerelease/`. 402 4036. (Optional) The previous steps actually only rebuild 404`https://jjfan.github.io/jj/prerelease/` and its alias 405`https://jjfan.github.io/jj/main/`. If you'd like to test out version switching 406back and forth, you can also rebuild the docs for the latest release as follows. 407 408 ```shell 409 jj new v1.33.1 # Let's say `jj 1.33.1` is the currently the latest release 410 .github/scripts/docs-build-deploy v1.33.1 latest --push 411 ``` 412 4137. (Optional) When you are done, you may want to reset the `gh-pages` bookmark to the 414same spot as it is upstream. If you configured the "upstream" remote, 415this can be done with: 416 417 ```shell 418 # This will LOSE any changes you made to `gh-pages` 419 jj git fetch --remote upstream 420 jj bookmark set gh-pages -r gh-pages@upstream 421 jj git push --remote origin --bookmark gh-pages 422 ``` 423 424 If you want to preserve some of the changes you made, you can do `jj bookmark 425 set my-changes -r gh-pages` BEFORE running the above commands. 426 427### Explanation of the `docs-build-deploy` script 428 429The script sets up a few environment variables and invokes `uv run mike deploy` 430with some default arguments and whatever arguments were passed to 431`docs-build-deploy`. Run `uv run mike help deploy` to find out what the 432arguments do. 433 434If you need to do something more complicated, you can use `uv run mike 435...` commands. You can also edit the `gh-pages` bookmark directly, but take care 436to avoid files that will be overwritten by future invocations of `mike`. Then, 437you can submit a PR based on the `gh-pages` bookmark of 438<https://jj-vcs.github.com/jj> (instead of the usual `main` bookmark). 439 440Previously, the version switcher would not work unless the value of the 441`site_url` config in `mkdocs.yml` matched the actual URL the site is being 442served from. This bug should now be fixed, but if you are not serving the site 443from https://jj-vcs.github.com/jj and something does not work weirdly, you might 444want to adjust the `site_url` to something like `https://jjfan.github.io/jj`. 445 446 447## Modifying protobuffers (this is not common) 448 449 Occasionally, you may need to change the `.proto` files that define jj's data 450 storage format. In this case, you will need to add a few steps to the above 451 workflow. 452 453 - Install the `protoc` compiler. This usually means either `apt-get install 454 protobuf-compiler` or downloading [an official release]. The 455 `prost` [library docs] have additional advice. 456 - Run `cargo run -p gen-protos` regularly (or after every edit to a `.proto` 457 file). This is the same as running `cargo run` from `lib/gen-protos`. The 458 `gen-protos` binary will use the `prost-build` library to compile the 459 `.proto` files into `.rs` files. 460 - If you are adding a new `.proto` file, you will need to edit the list of 461 these files in `lib/gen-protos/src/main.rs`. 462 463[an official release]: https://github.com/protocolbuffers/protobuf/releases 464[library docs]: https://docs.rs/prost-build/latest/prost_build/#sourcing-protoc 465 466 The `.rs` files generated from `.proto` files are included in the repository, 467 and there is a GitHub CI check that will complain if they do not match. 468 469## Logging 470 471You can print internal jj logs using `JJ_LOG`. It acts like the `RUST_LOG` 472environment variable, frequent in Rust codebases, and accepts one or more 473[directives]. You can also run `JJ_LOG=debug jj` to get `debug` level logs 474enabled for all targets. You can also use the `--debug` global option, which 475turns on `debug` log level for `jj-lib` and `jj-cli` only. 476 477[directives]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives 478 479## Profiling 480 481One easy-to-use sampling profiler 482is [samply](https://github.com/mstange/samply). For example: 483```shell 484cargo install samply 485samply record jj diff 486``` 487Then just open the link it prints. 488 489Another option is to use the instrumentation we've added manually (using 490`tracing::instrument`) in various places. For example: 491```shell 492JJ_TRACE=/tmp/trace.json jj diff 493``` 494Then go to `https://ui.perfetto.dev/` in Chrome and load `/tmp/trace.json` from 495there.