From 302cfc38d5e5a856955d7f8c9ca4335e89e39b4a Mon Sep 17 00:00:00 2001 From: Waleed Khan Date: Thu, 23 May 2024 19:15:59 -0700 Subject: [PATCH] cleanup: format `*.md` --- .github/ISSUE_TEMPLATE/bug_report.md | 10 +- .github/ISSUE_TEMPLATE/feature_request.md | 7 +- .github/PULL_REQUEST_TEMPLATE.md | 1 + CHANGELOG.md | 1267 ++++++++++----------- README.md | 34 +- cli/src/config/README.md | 2 +- demos/README.md | 2 +- docs/FAQ.md | 21 +- docs/branches.md | 28 +- docs/cli-reference.md | 2 - docs/code-of-conduct.md | 21 +- docs/config.md | 123 +- docs/conflicts.md | 19 +- docs/contributing.md | 111 +- docs/design/run.md | 248 ++-- docs/design/sparse-v2.md | 4 +- docs/design/tracking-branches.md | 217 ++-- docs/filesets.md | 30 +- docs/git-comparison.md | 23 +- docs/git-compatibility.md | 71 +- docs/github.md | 6 +- docs/index.md | 1 + docs/install-and-setup.md | 7 +- docs/operation-log.md | 7 +- docs/related-work.md | 12 +- docs/revsets.md | 114 +- docs/sapling-comparison.md | 36 +- docs/technical/architecture.md | 5 +- docs/technical/concurrency.md | 5 +- docs/technical/conflicts.md | 6 +- docs/templates.md | 198 ++-- docs/testimonials.md | 20 +- docs/tutorial.md | 54 +- docs/windows.md | 4 +- docs/working-copy.md | 8 +- 35 files changed, 1358 insertions(+), 1366 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index a7cab67dbb..6076ecf579 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,10 +1,9 @@ --- name: Bug report about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - +title: "" +labels: "" +assignees: "" --- ## Description @@ -13,7 +12,6 @@ assignees: '' For questions, use https://github.com/martinvonz/jj/discussions/new instead. Feel free to remove any of the sections below if they don't seem useful. --> - ## Steps to Reproduce the Problem 1. @@ -22,10 +20,8 @@ Feel free to remove any of the sections below if they don't seem useful. --> ## Expected Behavior - ## Actual Behavior - ## Specifications - Platform: diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 64373bfe09..06dea866c2 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,10 +1,9 @@ --- name: Feature request about: Suggest an idea for this project -title: 'FR: ' -labels: '' -assignees: '' - +title: "FR: " +labels: "" +assignees: "" --- **Is your feature request related to a problem? Please describe.** diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7a0bd95ec4..fd6c5f9f28 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -12,6 +12,7 @@ Note that you need to sign Google's CLA to contribute. # Checklist If applicable: + - [ ] I have updated `CHANGELOG.md` - [ ] I have updated the documentation (README.md, docs/, demos/) - [ ] I have updated the config schema (cli/src/config-schema.json) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f126599d2..8daed6eedd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,15 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Breaking changes -* Dropped support for `ui.default-revset` config (replaced by `revsets.log` in +- Dropped support for `ui.default-revset` config (replaced by `revsets.log` in 0.8.0). -* The `commit_summary_no_branches` template is superseded by +- The `commit_summary_no_branches` template is superseded by `templates.branch_list`. -* `jj split` will now refuse to split an empty commit. +- `jj split` will now refuse to split an empty commit. -* `jj config list` now uses multi-line strings and single-quoted strings in the +- `jj config list` now uses multi-line strings and single-quoted strings in the output when appropriate. ### Deprecations @@ -26,120 +26,121 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### New features -* `jj branch list`/`tag list` now accept `-T`/`--template` option. The tag list +- `jj branch list`/`tag list` now accept `-T`/`--template` option. The tag list prints commit summary along with the tag name by default. -* Conflict markers now include an explanation of what each part of the conflict +- Conflict markers now include an explanation of what each part of the conflict represents. -* `ui.color = "debug"` prints active labels alongside the regular colored output. +- `ui.color = "debug"` prints active labels alongside the regular colored output. -* `jj branch track` now show conflicts if there are some. +- `jj branch track` now show conflicts if there are some. -* A new revset `reachable(srcs, domain)` will return all commits that are +- A new revset `reachable(srcs, domain)` will return all commits that are reachable from `srcs` within `domain`. -* There are now prebuilt binaries for `aarch64-linux-unknown-musl`. +- There are now prebuilt binaries for `aarch64-linux-unknown-musl`. Note, these are cross compiled and currently untested. We plan on providing fully tested builds later once our CI system allows it. -* Added new revsets `mutable()` and `immutable()`. +- Added new revsets `mutable()` and `immutable()`. ### Fixed bugs -* When the working copy commit becomes immutable, a new one is automatically created on top of it -to avoid letting the user edit the immutable one. +- When the working copy commit becomes immutable, a new one is automatically created on top of it + to avoid letting the user edit the immutable one. -* `jj config list` now properly escapes TOML keys (#1322). +- `jj config list` now properly escapes TOML keys (#1322). -* Files with conflicts are now checked out as executable if all sides of the +- Files with conflicts are now checked out as executable if all sides of the conflict are executable. ## [0.17.1] - 2024-05-07 ### Fixed bugs -* `jj status` no longer scans through the entire history to look for ancestors with conflicts. +- `jj status` no longer scans through the entire history to look for ancestors with conflicts. ## [0.17.0] - 2024-05-01 ### Breaking changes -* The default template aliases were replaced as follows: - * `builtin_op_log_root(op_id: OperationId)` -> +- The default template aliases were replaced as follows: + + - `builtin_op_log_root(op_id: OperationId)` -> `format_root_operation(root: Operation)` - * `builtin_log_root(change_id: ChangeId, commit_id: CommitId)` -> + - `builtin_log_root(change_id: ChangeId, commit_id: CommitId)` -> `format_root_commit(root: Commit)` - * `builtin_change_id_with_hidden_and_divergent_info` -> + - `builtin_change_id_with_hidden_and_divergent_info` -> `format_short_change_id_with_hidden_and_divergent_info(commit: Commit)` -* The `--revision` option of `jj rebase` is renamed to `--revisions`. The short +- The `--revision` option of `jj rebase` is renamed to `--revisions`. The short alias `-r` is still supported. ### New features -* The list of conflicted paths is printed whenever the working copy changes. +- The list of conflicted paths is printed whenever the working copy changes. This can be disabled with the `--quiet` option. -* Commit objects in templates now have a `mine() -> Boolean` method analog to +- Commit objects in templates now have a `mine() -> Boolean` method analog to the same function in revsets. It evaluates to true if the email of the commit author matches the current `user.email`. -* Commit objects in templates now have a `contained_in(revset: String) -> - Boolean` method. +- Commit objects in templates now have a `contained_in(revset: String) -> +Boolean` method. -* Operation objects in templates now have a `snapshot() -> Boolean` method that +- Operation objects in templates now have a `snapshot() -> Boolean` method that evaluates to true if the operation was a snapshot created by a non-mutating command (e.g. `jj log`). -* Revsets and templates now support single-quoted raw string literals. +- Revsets and templates now support single-quoted raw string literals. -* A new config option `ui.always-allow-large-revsets` has been added to +- A new config option `ui.always-allow-large-revsets` has been added to allow large revsets expressions in some commands, without the `all:` prefix. -* A new config option `ui.allow-filesets` has been added to enable ["fileset" +- A new config option `ui.allow-filesets` has been added to enable ["fileset" expressions](docs/filesets.md). Note that filesets are currently experimental, but will be enabled by default in a future release. -* A new global flag `--ignore-immutable` lets you rewrite immutable commits. +- A new global flag `--ignore-immutable` lets you rewrite immutable commits. -* New command `jj parallelize` that rebases a set of revisions into siblings. +- New command `jj parallelize` that rebases a set of revisions into siblings. -* `jj status` now supports filtering by paths. For example, `jj status .` will +- `jj status` now supports filtering by paths. For example, `jj status .` will only list changed files that are descendants of the current directory. -* `jj prev` and `jj next` now work when the working copy revision is a merge. +- `jj prev` and `jj next` now work when the working copy revision is a merge. -* `jj squash` now accepts a `--use-destination-message/-u` option that uses the +- `jj squash` now accepts a `--use-destination-message/-u` option that uses the description of the destination for the new squashed revision and discards the descriptions of the source revisions. -* You can check whether Watchman fsmonitor is enabled or installed with the new +- You can check whether Watchman fsmonitor is enabled or installed with the new `jj debug watchman status` command. -* `jj rebase` now accepts revsets resolving to multiple revisions with the - `--revisions`/`-r` option. +- `jj rebase` now accepts revsets resolving to multiple revisions with the + `--revisions`/`-r` option. -* `jj rebase -r` now accepts `--insert-after` and `--insert-before` options to +- `jj rebase -r` now accepts `--insert-after` and `--insert-before` options to customize the location of the rebased revisions. ### Fixed bugs -* Revsets now support `\`-escapes in string literal. +- Revsets now support `\`-escapes in string literal. -* The builtin diff editor now allows empty files to be selected during +- The builtin diff editor now allows empty files to be selected during `jj split`. -* Fixed a bug with `jj split` introduced in 0.16.0 that caused it to incorrectly +- Fixed a bug with `jj split` introduced in 0.16.0 that caused it to incorrectly rebase the children of the revision being split if they had other parents (i.e. if the child was a merge). -* The `snapshot.max-new-file-size` option can now handle raw integer literals, +- The `snapshot.max-new-file-size` option can now handle raw integer literals, interpreted as a number of bytes, where previously it could only handle string literals. This means that `snapshot.max-new-file-size="1"` and `snapshot.max-new-file-size=1` are now equivalent. -* `jj squash ` is now a no-op if the path argument didn't match any paths +- `jj squash ` is now a no-op if the path argument didn't match any paths (it used to create new commits with bumped timestamp). [#3334](https://github.com/martinvonz/jj/issues/3334) @@ -147,88 +148,88 @@ to avoid letting the user edit the immutable one. Thanks to the people who made this release happen! -* Anton Älgmyr (@algmyr) -* Anton Bulakh (@necauqua) -* Austin Seipp (@thoughtpolice) -* Benjamin Tan (@bnjmnt4n) -* Cretezy (@Cretezy) -* Daniel Ploch (@torquestomp) -* Evan Mesterhazy (@emesterhazy) -* Ilya Grigoriev (@ilyagr) -* Martin von Zweigbergk (@martinvonz) -* Noah Mayr (@noahmayr) -* Jeremy O'Brien (@neutralinsomniac) -* Jonathan Lorimer (@JonathanLorimer) -* Philip Metzger (@PhilipMetzger) -* Poliorcetics (@poliorcetics) -* Rowan Walsh (@rowan-walsh) -* Scott Olson (@solson) -* Théo Daron (@Kaporos) -* Yuya Nishihara (@yuja) - +- Anton Älgmyr (@algmyr) +- Anton Bulakh (@necauqua) +- Austin Seipp (@thoughtpolice) +- Benjamin Tan (@bnjmnt4n) +- Cretezy (@Cretezy) +- Daniel Ploch (@torquestomp) +- Evan Mesterhazy (@emesterhazy) +- Ilya Grigoriev (@ilyagr) +- Martin von Zweigbergk (@martinvonz) +- Noah Mayr (@noahmayr) +- Jeremy O'Brien (@neutralinsomniac) +- Jonathan Lorimer (@JonathanLorimer) +- Philip Metzger (@PhilipMetzger) +- Poliorcetics (@poliorcetics) +- Rowan Walsh (@rowan-walsh) +- Scott Olson (@solson) +- Théo Daron (@Kaporos) +- Yuya Nishihara (@yuja) ## [0.16.0] - 2024-04-03 ### Deprecations -* `jj move` was deprecated in favor of `jj squash`. +- `jj move` was deprecated in favor of `jj squash`. ### Breaking changes -* The `git_head` template keyword now returns an optional value instead of a +- The `git_head` template keyword now returns an optional value instead of a list of 0 or 1 element. -* The `jj sparse set --edit`/`--reset` flags were split up into `jj sparse - edit`/`reset` subcommands respectively. +- The `jj sparse set --edit`/`--reset` flags were split up into `jj sparse +edit`/`reset` subcommands respectively. -* The `jj sparse` subcommands now parse and print patterns as workspace-relative +- The `jj sparse` subcommands now parse and print patterns as workspace-relative paths. -* The `jj log` command no longer uses the default revset when a path is specified. +- The `jj log` command no longer uses the default revset when a path is specified. ### New features -* Config now supports rgb hex colors (in the form `#rrggbb`) wherever existing color names are supported. +- Config now supports rgb hex colors (in the form `#rrggbb`) wherever existing color names are supported. -* `ui.default-command` now accepts multiple string arguments, for more complex +- `ui.default-command` now accepts multiple string arguments, for more complex default `jj` commands. -* Graph node symbols are now configurable via templates - * `templates.log_node` - * `templates.op_log_node` +- Graph node symbols are now configurable via templates -* `jj log` now includes synthetic nodes in the graph where some revisions were + - `templates.log_node` + - `templates.op_log_node` + +- `jj log` now includes synthetic nodes in the graph where some revisions were elided. -* `jj squash` now accepts `--from` and `--into` (also aliased as `--to`) if `-r` +- `jj squash` now accepts `--from` and `--into` (also aliased as `--to`) if `-r` is not specified. It can now be used for all use cases where `jj move` could previously be used. The `--from` argument accepts a revset that resolves to more than one revision. -* Commit templates now support `immutable` keyword. +- Commit templates now support `immutable` keyword. -* New template function `coalesce(content, ..)` is added. +- New template function `coalesce(content, ..)` is added. -* Timestamps are now shown in local timezone and without milliseconds and +- Timestamps are now shown in local timezone and without milliseconds and timezone offset by default. -* `jj git push` now prints messages from the remote. +- `jj git push` now prints messages from the remote. -* `jj branch list` now supports a `--conflicted/-c` option to show only conflicted branches. +- `jj branch list` now supports a `--conflicted/-c` option to show only conflicted branches. -* `jj duplicate` and `jj abandon` can now take more than a single `-r` argument, +- `jj duplicate` and `jj abandon` can now take more than a single `-r` argument, for consistency with other commands. -* `jj branch list` now allows combining `-r REVISIONS`/`NAMES` and `-a` options. +- `jj branch list` now allows combining `-r REVISIONS`/`NAMES` and `-a` options. -* `--all` is now named `--all-remotes` for `jj branch list` +- `--all` is now named `--all-remotes` for `jj branch list` -* There is a new global `--quiet` flag to silence commands' non-primary output. +- There is a new global `--quiet` flag to silence commands' non-primary output. -* `jj split` now supports a `--siblings/-s` option that splits the target +- `jj split` now supports a `--siblings/-s` option that splits the target revision into siblings with the same parents and children. -* New function `working_copies()` for revsets to show the working copy commits of all workspaces. +- New function `working_copies()` for revsets to show the working copy commits of all workspaces. ### Fixed bugs @@ -238,28 +239,27 @@ None. Thanks to the people who made this release happen! -* Aleksey Kuznetsov (@zummenix) -* Anton Älgmyr (@algmyr) -* Austin Seipp (@thoughtpolice) -* Benjamin Tan (@bnjmnt4n) -* Chris Krycho (@chriskrycho) -* Christoph Koehler (@ckoehler) -* Daniel Ploch (@torquestomp) -* Evan Mesterhazy (@emesterhazy) -* Ilya Grigoriev (@ilyagr) -* Khionu Sybiern (@khionu) -* Martin von Zweigbergk (@martinvonz) -* Matthew Davidson (@KingMob) -* mrstanwell (@mrstanwell) -* Noah Mayr (@noahmayr) -* Patric Stout (@TrueBrain) -* Poliorcetics (@poliorcetics) -* Simon Wollwage (@Kintaro) -* Steve Klabnik (@steveklabnik) -* Tom Ward (@tomafro) -* TrashCan (@TrashCan69420) -* Yuya Nishihara (@yuja) - +- Aleksey Kuznetsov (@zummenix) +- Anton Älgmyr (@algmyr) +- Austin Seipp (@thoughtpolice) +- Benjamin Tan (@bnjmnt4n) +- Chris Krycho (@chriskrycho) +- Christoph Koehler (@ckoehler) +- Daniel Ploch (@torquestomp) +- Evan Mesterhazy (@emesterhazy) +- Ilya Grigoriev (@ilyagr) +- Khionu Sybiern (@khionu) +- Martin von Zweigbergk (@martinvonz) +- Matthew Davidson (@KingMob) +- mrstanwell (@mrstanwell) +- Noah Mayr (@noahmayr) +- Patric Stout (@TrueBrain) +- Poliorcetics (@poliorcetics) +- Simon Wollwage (@Kintaro) +- Steve Klabnik (@steveklabnik) +- Tom Ward (@tomafro) +- TrashCan (@TrashCan69420) +- Yuya Nishihara (@yuja) ## [0.15.1] - 2024-03-06 @@ -269,105 +269,106 @@ No code changes (fixing Rust `Cargo.toml` stuff). ### Breaking changes -* The minimum supported Rust version (MSRV) is now 1.76.0. +- The minimum supported Rust version (MSRV) is now 1.76.0. -* The on-disk index format changed. New index files will be created +- The on-disk index format changed. New index files will be created automatically, but it can fail if the repository is co-located and predates Git GC issues [#815](https://github.com/martinvonz/jj/issues/815). If reindexing failed, you'll need to clean up corrupted operation history by `jj op abandon ..`. -* Dropped support for the "legacy" graph-drawing style. Use "ascii" for a very +- Dropped support for the "legacy" graph-drawing style. Use "ascii" for a very similar result. -* The default log output no longer lists all tagged heads. Set `revsets.log = - "@ | ancestors(immutable_heads().., 2) | heads(immutable_heads())"` to restore +- The default log output no longer lists all tagged heads. Set `revsets.log = +"@ | ancestors(immutable_heads().., 2) | heads(immutable_heads())"` to restore the old behavior. -* Dropped support for the deprecated `:` revset operator. Use `::` instead. +- Dropped support for the deprecated `:` revset operator. Use `::` instead. -* `jj rebase --skip-empty` no longer abandons commits that were already empty +- `jj rebase --skip-empty` no longer abandons commits that were already empty before the rebase. ### New features -* Partial support for commit signing. Currently you can configure jj to "keep" +- Partial support for commit signing. Currently you can configure jj to "keep" commit signatures by making new ones for rewritten commits, and to sign new commits when they are created. This comes with out-of-the-box support for the following backends: - * GnuPG - * SSH + + - GnuPG + - SSH Signature verification and an explicit sign command will hopefully come soon. -* Templates now support logical operators: `||`, `&&`, `!` +- Templates now support logical operators: `||`, `&&`, `!` -* Templates now support the `self` keyword, which is the current commit in `jj - log`/`obslog` templates. +- Templates now support the `self` keyword, which is the current commit in `jj +log`/`obslog` templates. -* `jj show` now accepts `-T`/`--template` option to render its output using +- `jj show` now accepts `-T`/`--template` option to render its output using template -* `jj config list` now accepts `-T`/`--template` option. +- `jj config list` now accepts `-T`/`--template` option. -* `jj git fetch` now accepts `-b` as a shorthand for `--branch`, making it more +- `jj git fetch` now accepts `-b` as a shorthand for `--branch`, making it more consistent with other commands that accept a branch -* In the templating language, Timestamps now have a `.local()` method for +- In the templating language, Timestamps now have a `.local()` method for converting to the local timezone. -* `jj next/prev` now infer `--edit` when you're already editing a non-head +- `jj next/prev` now infer `--edit` when you're already editing a non-head commit (a commit with children). -* A new built-in pager named `:builtin` is available on all platforms, +- A new built-in pager named `:builtin` is available on all platforms, implemented with [minus](https://github.com/arijit79/minus/) -* Set config `ui.log-synthetic-elided-nodes = true` to make `jj log` include +- Set config `ui.log-synthetic-elided-nodes = true` to make `jj log` include synthetic nodes in the graph where some revisions were elided ([#1252](https://github.com/martinvonz/jj/issues/1252), [#2971](https://github.com/martinvonz/jj/issues/2971)). This may become the default depending on feedback. -* When creating a new workspace, the sparse patterns are now copied over from +- When creating a new workspace, the sparse patterns are now copied over from the current workspace. -* `jj git init --colocate` can now import an existing Git repository. This is +- `jj git init --colocate` can now import an existing Git repository. This is equivalent to `jj git init --git-repo=.`. -* `jj git fetch` now automatically prints new remote branches and tags by default. +- `jj git fetch` now automatically prints new remote branches and tags by default. -* `--verbose/-v` is now `--debug` (no short option since it's not intended to be used often) +- `--verbose/-v` is now `--debug` (no short option since it's not intended to be used often) -* `jj move --from/--to` can now be abbreviated to `jj move -f/-t` +- `jj move --from/--to` can now be abbreviated to `jj move -f/-t` -* `jj commit`/`diffedit`/`move`/`resolve`/`split`/`squash`/`unsquash` now accept +- `jj commit`/`diffedit`/`move`/`resolve`/`split`/`squash`/`unsquash` now accept `--tool=` option to override the default. - [#2575](https://github.com/martinvonz/jj/issues/2575) + [#2575](https://github.com/martinvonz/jj/issues/2575) -* Added completions for [Nushell](https://nushell.sh) to `jj util completion` +- Added completions for [Nushell](https://nushell.sh) to `jj util completion` -* `jj branch list` now supports a `--tracked/-t` option which can be used to +- `jj branch list` now supports a `--tracked/-t` option which can be used to show tracked branches only. Omits local Git-tracking branches by default. -* Commands producing diffs now accept a `--context` flag for the number of +- Commands producing diffs now accept a `--context` flag for the number of lines of context to show. -* `jj` commands with the `-T`/`--template` option now provide a hint containing +- `jj` commands with the `-T`/`--template` option now provide a hint containing defined template names when no argument is given, assisting the user in making a selection. ### Fixed bugs -* On Windows, symlinks in the repo are now supported when Developer Mode is enabled. +- On Windows, symlinks in the repo are now supported when Developer Mode is enabled. When symlink support is unavailable, they will be materialized as regular files in the working copy (instead of resulting in a crash). [#2](https://github.com/martinvonz/jj/issues/2) -* On Windows, the `:builtin` pager is now used by default, rather than being +- On Windows, the `:builtin` pager is now used by default, rather than being disabled entirely. -* Auto-rebase now preserves the shape of history even for merge commits where +- Auto-rebase now preserves the shape of history even for merge commits where one parent is an ancestor of another. [#2600](https://github.com/martinvonz/jj/issues/2600) @@ -375,43 +376,42 @@ No code changes (fixing Rust `Cargo.toml` stuff). Thanks to the people who made this release happen! -* Aleksey Kuznetsov (@zummenix) -* Anton Bulakh (@necauqua) -* Anton Älgmyr (@algmyr) -* Austin Seipp (@thoughtpolice) -* Benjamin Brittain (@benbrittain) -* Benjamin Tan (@bnjmnt4n) -* Daehyeok Mun (@daehyeok) -* Daniel Ploch (@torquestomp) -* Evan Mesterhazy (@emesterhazy) -* gulbanana (@gulbanana) -* Ilya Grigoriev (@ilyagr) -* Jonathan Tan (@jonathantanmy) -* Julien Vincent (@julienvincent) -* jyn (@jyn514) -* Martin von Zweigbergk (@martinvonz) -* Paulo Coelho (@prscoelho) -* Philip Metzger (@PhilipMetzger) -* Poliorcetics (@poliorcetics) -* Stephen Jennings (@jennings) -* Vladimir (@0xdeafbeef) -* Yuya Nishihara (@yuja) - +- Aleksey Kuznetsov (@zummenix) +- Anton Bulakh (@necauqua) +- Anton Älgmyr (@algmyr) +- Austin Seipp (@thoughtpolice) +- Benjamin Brittain (@benbrittain) +- Benjamin Tan (@bnjmnt4n) +- Daehyeok Mun (@daehyeok) +- Daniel Ploch (@torquestomp) +- Evan Mesterhazy (@emesterhazy) +- gulbanana (@gulbanana) +- Ilya Grigoriev (@ilyagr) +- Jonathan Tan (@jonathantanmy) +- Julien Vincent (@julienvincent) +- jyn (@jyn514) +- Martin von Zweigbergk (@martinvonz) +- Paulo Coelho (@prscoelho) +- Philip Metzger (@PhilipMetzger) +- Poliorcetics (@poliorcetics) +- Stephen Jennings (@jennings) +- Vladimir (@0xdeafbeef) +- Yuya Nishihara (@yuja) ## [0.14.0] - 2024-02-07 ### Deprecations -* `jj checkout` and `jj merge` are both deprecated; use `jj new` instead to +- `jj checkout` and `jj merge` are both deprecated; use `jj new` instead to replace both of these commands in all instances. **Rationale**: `jj checkout` and `jj merge` both implement identical functionality, which is a subset of `jj new`. `checkout` creates a new working copy commit on top of a single specified revision, i.e. with one parent. - `merge` creates a new working copy commit on top of *at least* two specified + `merge` creates a new working copy commit on top of _at least_ two specified revisions, i.e. with two or more parents. - The only difference between these commands and `jj new`, which *also* creates + The only difference between these commands and `jj new`, which _also_ creates a new working copy commit, is that `new` can create a working copy commit on top of any arbitrary number of revisions, so it can handle both the previous cases at once. The only actual difference between these three commands is the @@ -426,77 +426,76 @@ Thanks to the people who made this release happen! **Deadline**: `jj checkout` and `jj merge` will be deleted and are expected become a **hard error later in 2024**. -* `jj init --git` and `jj init --git-repo` are now deprecated and will be removed +- `jj init --git` and `jj init --git-repo` are now deprecated and will be removed in the near future. Use `jj git init` instead. - ### Breaking changes -* (Minor) Diff summaries (e.g. `jj diff -s`) now use `D` for "Deleted" instead +- (Minor) Diff summaries (e.g. `jj diff -s`) now use `D` for "Deleted" instead of `R` for "Removed". @joyously pointed out that `R` could also mean "Renamed". -* `jj util completion` now takes the shell as a positional argument, not a flag. +- `jj util completion` now takes the shell as a positional argument, not a flag. the previous behavior is deprecated, but supported for now. it will be removed in the future. -* `jj rebase` now preserves the shape of history even for merge commits where +- `jj rebase` now preserves the shape of history even for merge commits where one parent is an ancestor of another. You can follow the `jj rebase` by `jj rebase -s -d ` if you want to linearize the history. ### New features -* `jj util completion` now supports powershell and elvish. +- `jj util completion` now supports powershell and elvish. -* Official binaries for macOS running on Apple Silicon (`aarch64-apple-darwin`) +- Official binaries for macOS running on Apple Silicon (`aarch64-apple-darwin`) are now available, alongside the existing macOS x86 binaries. -* New `jj op abandon` command is added to clean up the operation history. Git +- New `jj op abandon` command is added to clean up the operation history. Git refs and commit objects can be further compacted by `jj util gc`. -* `jj util gc` now removes unreachable operation, view, and Git objects. +- `jj util gc` now removes unreachable operation, view, and Git objects. -* `jj branch rename` will now warn if the renamed branch has a remote branch, since +- `jj branch rename` will now warn if the renamed branch has a remote branch, since those will have to be manually renamed outside of `jj`. -* `jj git push` gained a `--tracked` option, to push all the tracked branches. +- `jj git push` gained a `--tracked` option, to push all the tracked branches. -* There's now a virtual root operation, similar to the [virtual root +- There's now a virtual root operation, similar to the [virtual root commit](docs/glossary.md#root-commit). It appears at the end of `jj op log`. -* `jj config list` gained a `--include-overridden` option to allow +- `jj config list` gained a `--include-overridden` option to allow printing overridden config values. -* `jj config list` now accepts `--user` or `--repo` option to specify +- `jj config list` now accepts `--user` or `--repo` option to specify config origin. -* New `jj config path` command to print the config file path without launching +- New `jj config path` command to print the config file path without launching an editor. -* `jj tag list` command prints imported git tags. +- `jj tag list` command prints imported git tags. -* `jj next` and `jj prev` now prompt in the event of the next/previous commit +- `jj next` and `jj prev` now prompt in the event of the next/previous commit being ambiguous, instead of failing outright. -* `jj resolve` now displays the file being resolved. +- `jj resolve` now displays the file being resolved. -* `jj workspace root` was aliased to `jj root`, for ease of discoverability +- `jj workspace root` was aliased to `jj root`, for ease of discoverability -* `jj diff` no longer shows the contents of binary files. +- `jj diff` no longer shows the contents of binary files. -* `jj git` now has an `init` command that initializes a git backed repo. +- `jj git` now has an `init` command that initializes a git backed repo. -* New template function `surround(prefix, suffix, content)` is added. +- New template function `surround(prefix, suffix, content)` is added. ### Fixed bugs -* Fixed snapshots of symlinks in `gitignore`-d directory. +- Fixed snapshots of symlinks in `gitignore`-d directory. [#2878](https://github.com/martinvonz/jj/issues/2878) -* Fixed data loss in dirty working copy when checked-out branch is rebased or +- Fixed data loss in dirty working copy when checked-out branch is rebased or abandoned by Git. [#2876](https://github.com/martinvonz/jj/issues/2876) @@ -504,43 +503,42 @@ Thanks to the people who made this release happen! Thanks to the people who made this release happen! -* Austin Seipp (@thoughtpolice) -* Benjamin Brittain (@benbrittain) -* Chris Krycho (@chriskrycho) -* Daehyeok Mun (@daehyeok) -* Daniel Ploch (@torquestomp) -* Essien Ita Essien (@essiene) -* Ikko Eltociear Ashimine (@eltociear) -* Ilya Grigoriev (@ilyagr) -* Jonathan Tan (@jonathantanmy) -* jyn (@jyn514) -* Martin von Zweigbergk (@martinvonz) -* Matt Stark (@matts1) -* Michael Pratt (prattmic) -* Philip Metzger (@PhilipMetzger) -* Stephen Jennings (@jennings) -* Valentin Gatien-Baron (@v-gb) -* vwkd (@vwkd) -* Yuya Nishihara (@yuja) - +- Austin Seipp (@thoughtpolice) +- Benjamin Brittain (@benbrittain) +- Chris Krycho (@chriskrycho) +- Daehyeok Mun (@daehyeok) +- Daniel Ploch (@torquestomp) +- Essien Ita Essien (@essiene) +- Ikko Eltociear Ashimine (@eltociear) +- Ilya Grigoriev (@ilyagr) +- Jonathan Tan (@jonathantanmy) +- jyn (@jyn514) +- Martin von Zweigbergk (@martinvonz) +- Matt Stark (@matts1) +- Michael Pratt (prattmic) +- Philip Metzger (@PhilipMetzger) +- Stephen Jennings (@jennings) +- Valentin Gatien-Baron (@v-gb) +- vwkd (@vwkd) +- Yuya Nishihara (@yuja) ## [0.13.0] - 2024-01-03 ### Breaking changes -* `jj git fetch` no longer imports new remote branches as local branches. Set +- `jj git fetch` no longer imports new remote branches as local branches. Set `git.auto-local-branch = true` to restore the old behavior. ### New features -* Information about new and resolved conflicts is now printed by every command. +- Information about new and resolved conflicts is now printed by every command. -* `jj branch` has gained a new `rename` subcommand that allows changing a branch +- `jj branch` has gained a new `rename` subcommand that allows changing a branch name atomically. `jj branch help rename` for details. ### Fixed bugs -* Command aliases can now be loaded from repository config relative to the +- Command aliases can now be loaded from repository config relative to the current working directory. [#2414](https://github.com/martinvonz/jj/issues/2414) @@ -548,53 +546,52 @@ Thanks to the people who made this release happen! Thanks to the people who made this release happen! -* Austin Seipp (@thoughtpolice) -* Essien Ita Essien (@essiene) -* Gabriel Scherer (@gasche) -* Ilya Grigoriev (@ilyagr) -* Martin von Zweigbergk (@martinvonz) -* Philip Metzger (@PhilipMetzger) -* Waleed Khan (@arxanas) -* Yuya Nishihara (@yuja) - +- Austin Seipp (@thoughtpolice) +- Essien Ita Essien (@essiene) +- Gabriel Scherer (@gasche) +- Ilya Grigoriev (@ilyagr) +- Martin von Zweigbergk (@martinvonz) +- Philip Metzger (@PhilipMetzger) +- Waleed Khan (@arxanas) +- Yuya Nishihara (@yuja) ## [0.12.0] - 2023-12-05 ### Breaking changes -* The `remote_branches()` revset no longer includes branches exported to the Git +- The `remote_branches()` revset no longer includes branches exported to the Git repository (so called Git-tracking branches.) -* `jj branch set` no longer creates a new branch. Use `jj branch create` +- `jj branch set` no longer creates a new branch. Use `jj branch create` instead. -* `jj init --git` in an existing Git repository now errors and exits rather than +- `jj init --git` in an existing Git repository now errors and exits rather than creating a second Git store. ### New features -* `jj workspace add` can now take _multiple_ `--revision` arguments, which will +- `jj workspace add` can now take _multiple_ `--revision` arguments, which will create a new workspace with its working-copy commit on top of all the parents, as if you had run `jj new r1 r2 r3 ...`. -* You can now set `git.abandon-unreachable-commits = false` to disable the +- You can now set `git.abandon-unreachable-commits = false` to disable the usual behavior where commits that became unreachable in the Git repo are abandoned ([#2504](https://github.com/martinvonz/jj/pull/2504)). -* `jj new` gained a `--no-edit` option to prevent editing the newly created +- `jj new` gained a `--no-edit` option to prevent editing the newly created commit. For example, `jj new a b --no-edit -m Merge` creates a merge commit without affecting the working copy. -* `jj rebase` now takes the flag `--skip-empty`, which doesn't copy over commits +- `jj rebase` now takes the flag `--skip-empty`, which doesn't copy over commits that would become empty after a rebase. -* There is a new `jj util gc` command for cleaning up the repository storage. +- There is a new `jj util gc` command for cleaning up the repository storage. For now, it simply runs `git gc` on the backing Git repo (when using the Git backend). ### Fixed bugs -* Fixed another file conflict resolution issue where `jj status` would disagree +- Fixed another file conflict resolution issue where `jj status` would disagree with the actual file content. [#2654](https://github.com/martinvonz/jj/issues/2654) @@ -602,49 +599,48 @@ Thanks to the people who made this release happen! Thanks to the people who made this release happen! -* Antoine Cezar (@AntoineCezar) -* Anton Bulakh (@necauqua) -* Austin Seipp (@thoughtpolice) -* Benjamin Saunders (@Ralith) -* Carlos Precioso (@cprecioso) -* Chris Krycho (@chriskrycho) -* Ilya Grigoriev (@ilyagr) -* Jason R. Coombs (@jaraco) -* Jesse Somerville (@jessesomerville) -* Łukasz Kurowski (@crackcomm) -* Martin von Zweigbergk (@martinvonz) -* mlcui (@mlcui-google) -* Philip Metzger (@PhilipMetzger) -* Waleed Khan (@arxanas) -* Yuya Nishihara (@yuja) - +- Antoine Cezar (@AntoineCezar) +- Anton Bulakh (@necauqua) +- Austin Seipp (@thoughtpolice) +- Benjamin Saunders (@Ralith) +- Carlos Precioso (@cprecioso) +- Chris Krycho (@chriskrycho) +- Ilya Grigoriev (@ilyagr) +- Jason R. Coombs (@jaraco) +- Jesse Somerville (@jessesomerville) +- Łukasz Kurowski (@crackcomm) +- Martin von Zweigbergk (@martinvonz) +- mlcui (@mlcui-google) +- Philip Metzger (@PhilipMetzger) +- Waleed Khan (@arxanas) +- Yuya Nishihara (@yuja) ## [0.11.0] - 2023-11-01 ### Breaking changes -* Conflicts are now stored in a different way. Commits written by a new `jj` +- Conflicts are now stored in a different way. Commits written by a new `jj` binary will not be read correctly by older `jj` binaries. The new model solves some performance problems with the old model. For example, `jj log` should be noticeably faster on large repos. You may need to create a new clone to see the full speedup. -* The `remote_branches()` revset now includes branches exported to the Git - repository (so called Git-tracking branches.) *This change will be reverted - in 0.12.0.* +- The `remote_branches()` revset now includes branches exported to the Git + repository (so called Git-tracking branches.) _This change will be reverted + in 0.12.0._ -* Status messages are now printed to stderr. +- Status messages are now printed to stderr. -* `jj config set` now interprets the value as TOML also if it's a valid TOML +- `jj config set` now interprets the value as TOML also if it's a valid TOML array or table. For example, `jj config set --user 'aliases.n' '["new"]'` -* Remote branches now have tracking or non-tracking flags. The +- Remote branches now have tracking or non-tracking flags. The `git.auto-local-branch` setting is applied only to newly fetched remote branches. Existing remote branches are migrated as follows: - * If local branch exists, the corresponding remote branches are considered + - If local branch exists, the corresponding remote branches are considered tracking branches. - * Otherwise, the remote branches are non-tracking branches. + - Otherwise, the remote branches are non-tracking branches. If the deduced tracking flags are wrong, use `jj branch track`/`untrack` commands to fix them up. @@ -652,114 +648,113 @@ Thanks to the people who made this release happen! See [automatic local branch creation](docs/config.md#automatic-local-branch-creation) for details. -* Non-tracking remote branches aren't listed by default. Use `jj branch list - --all` to show all local and remote branches. +- Non-tracking remote branches aren't listed by default. Use `jj branch list +--all` to show all local and remote branches. -* It's not allowed to push branches if non-tracking remote branches of the same +- It's not allowed to push branches if non-tracking remote branches of the same name exist. -* Pushing deleted/moved branches no longer abandons the local commits referenced +- Pushing deleted/moved branches no longer abandons the local commits referenced by the remote branches. -* `jj git fetch --branch` now requires `glob:` prefix to expand `*` in branch +- `jj git fetch --branch` now requires `glob:` prefix to expand `*` in branch name. ### New features -* `jj`'s stable release can now be installed with [`cargo binstall jj-cli`](https://github.com/cargo-bins/cargo-binstall). +- `jj`'s stable release can now be installed with [`cargo binstall jj-cli`](https://github.com/cargo-bins/cargo-binstall). -* `jj workspace add` now takes a `--revision` argument. +- `jj workspace add` now takes a `--revision` argument. -* `jj workspace forget` can now forget multiple workspaces at once. +- `jj workspace forget` can now forget multiple workspaces at once. -* `branches()`/`remote_branches()`/`author()`/`committer()`/`description()` +- `branches()`/`remote_branches()`/`author()`/`committer()`/`description()` revsets now support glob matching. -* `jj branch delete`/`forget`/`list`, and `jj git push --branch` now support +- `jj branch delete`/`forget`/`list`, and `jj git push --branch` now support [string pattern syntax](docs/revsets.md#string-patterns). The `--glob` option is deprecated in favor of `glob:` pattern. -* The `branches`/`tags`/`git_refs`/`git_head` template keywords now return a +- The `branches`/`tags`/`git_refs`/`git_head` template keywords now return a list of `RefName`s. They were previously pre-formatted strings. -* The new template keywords `local_branches`/`remote_branches` are added to show +- The new template keywords `local_branches`/`remote_branches` are added to show only local/remote branches. -* `jj workspace add` now preserves all parents of the old working-copy commit +- `jj workspace add` now preserves all parents of the old working-copy commit instead of just the first one. -* `jj rebase -r` gained the ability to rebase a revision `A` onto a descendant +- `jj rebase -r` gained the ability to rebase a revision `A` onto a descendant of `A`. ### Fixed bugs -* Updating the working copy to a commit where a file that's currently ignored +- Updating the working copy to a commit where a file that's currently ignored in the working copy no longer leads to a crash ([#976](https://github.com/martinvonz/jj/issues/976)). -* Conflicts in executable files can now be resolved just like conflicts in +- Conflicts in executable files can now be resolved just like conflicts in non-executable files ([#1279](https://github.com/martinvonz/jj/issues/1279)). -* `jj new --insert-before` and `--insert-after` now respect immutable revisions +- `jj new --insert-before` and `--insert-after` now respect immutable revisions ([#2468](https://github.com/martinvonz/jj/pull/2468)). ### Contributors Thanks to the people who made this release happen! -* Antoine Cezar (@AntoineCezar) -* Austin Seipp (@thoughtpolice) -* Benjamin Saunders (@Ralith) -* Gabriel Scherer (@gasche) -* Ilya Grigoriev (@ilyagr) -* Infra (@1011X) -* Isabella Basso (@isinyaaa) -* Martin von Zweigbergk (@martinvonz) -* Tal Pressman (@talpr) -* Waleed Khan (@arxanas) -* Yuya Nishihara (@yuja) - +- Antoine Cezar (@AntoineCezar) +- Austin Seipp (@thoughtpolice) +- Benjamin Saunders (@Ralith) +- Gabriel Scherer (@gasche) +- Ilya Grigoriev (@ilyagr) +- Infra (@1011X) +- Isabella Basso (@isinyaaa) +- Martin von Zweigbergk (@martinvonz) +- Tal Pressman (@talpr) +- Waleed Khan (@arxanas) +- Yuya Nishihara (@yuja) ## [0.10.0] - 2023-10-04 ### Breaking changes -* A default revset-alias function `trunk()` now exists. If you previously defined +- A default revset-alias function `trunk()` now exists. If you previously defined your own `trunk()` alias it will continue to overwrite the built-in one. Check [revsets.toml](cli/src/config/revsets.toml) and [revsets.md](docs/revsets.md) to understand how the function can be adapted. ### New features -* The `ancestors()` revset function now takes an optional `depth` argument +- The `ancestors()` revset function now takes an optional `depth` argument to limit the depth of the ancestor set. For example, use `jj log -r - 'ancestors(@, 5)` to view the last 5 commits. +'ancestors(@, 5)` to view the last 5 commits. -* Support for the Watchman filesystem monitor is now bundled by default. Set +- Support for the Watchman filesystem monitor is now bundled by default. Set `core.fsmonitor = "watchman"` in your repo to enable. -* You can now configure the set of immutable commits via +- You can now configure the set of immutable commits via `revset-aliases.immutable_heads()`. For example, set it to `"remote_branches() | tags()"` to prevent rewriting those those. Their ancestors are implicitly also immutable. -* `jj op log` now supports `--no-graph`. +- `jj op log` now supports `--no-graph`. -* Templates now support an additional escape: `\0`. This will output a literal +- Templates now support an additional escape: `\0`. This will output a literal null byte. This may be useful for e.g. `jj log -T 'description ++ "\0"' --no-graph` to output descriptions only, but be able to tell where the boundaries are -* jj now bundles a TUI tool to use as the default diff and merge editors. (The +- jj now bundles a TUI tool to use as the default diff and merge editors. (The previous default was `meld`.) -* `jj split` supports the `--interactive` flag. (This is already the default if +- `jj split` supports the `--interactive` flag. (This is already the default if no paths are provided.) -* `jj commit` accepts an optional list of paths indicating a subset of files to +- `jj commit` accepts an optional list of paths indicating a subset of files to include in the first commit -* `jj commit` accepts the `--interactive` flag. +- `jj commit` accepts the `--interactive` flag. ### Fixed bugs @@ -767,165 +762,164 @@ Thanks to the people who made this release happen! Thanks to the people who made this release happen! -* Austin Seipp (@thoughtpolice) -* Emily Kyle Fox (@emilykfox) -* glencbz (@glencbz) -* Hong Shin (@honglooker) -* Ilya Grigoriev (@ilyagr) -* James Sully (@sullyj3) -* Martin von Zweigbergk (@martinvonz) -* Philip Metzger (@PhilipMetzger) -* Ruben Slabbert (@rslabbert) -* Vamsi Avula (@avamsi) -* Waleed Khan (@arxanas) -* Willian Mori (@wmrmrx)) -* Yuya Nishihara (@yuja) -* Zachary Dremann (@Dr-Emann) - +- Austin Seipp (@thoughtpolice) +- Emily Kyle Fox (@emilykfox) +- glencbz (@glencbz) +- Hong Shin (@honglooker) +- Ilya Grigoriev (@ilyagr) +- James Sully (@sullyj3) +- Martin von Zweigbergk (@martinvonz) +- Philip Metzger (@PhilipMetzger) +- Ruben Slabbert (@rslabbert) +- Vamsi Avula (@avamsi) +- Waleed Khan (@arxanas) +- Willian Mori (@wmrmrx)) +- Yuya Nishihara (@yuja) +- Zachary Dremann (@Dr-Emann) ## [0.9.0] - 2023-09-06 ### Breaking changes -* The minimum supported Rust version (MSRV) is now 1.71.0. +- The minimum supported Rust version (MSRV) is now 1.71.0. -* The storage format of branches, tags, and git refs has changed. Newly-stored +- The storage format of branches, tags, and git refs has changed. Newly-stored repository data will no longer be loadable by older binaries. -* The `:` revset operator is deprecated. Use `::` instead. We plan to delete the +- The `:` revset operator is deprecated. Use `::` instead. We plan to delete the `:` form in jj 0.15+. -* The `--allow-large-revsets` flag for `jj rebase` and `jj new` was replaced by +- The `--allow-large-revsets` flag for `jj rebase` and `jj new` was replaced by a `all:` before the revset. For example, use `jj rebase -d 'all:foo-'` instead of `jj rebase --allow-large-revsets -d 'foo-'`. -* The `--allow-large-revsets` flag for `jj rebase` and `jj new` can no longer be +- The `--allow-large-revsets` flag for `jj rebase` and `jj new` can no longer be used for allowing duplicate destinations. Include the potential duplicates in a single expression instead (e.g. `jj new 'all:x|y'`). -* The `push.branch-prefix` option was renamed to `git.push-branch-prefix`. +- The `push.branch-prefix` option was renamed to `git.push-branch-prefix`. -* The default editor on Windows is now `Notepad` instead of `pico`. +- The default editor on Windows is now `Notepad` instead of `pico`. -* `jj` will fail attempts to snapshot new files larger than 1MiB by default. This behavior +- `jj` will fail attempts to snapshot new files larger than 1MiB by default. This behavior can be customized with the `snapshot.max-new-file-size` config option. -* Author and committer signatures now use empty strings to represent unset +- Author and committer signatures now use empty strings to represent unset names and email addresses. The `author`/`committer` template keywords and methods also return empty strings. Older binaries may not warn user when attempting to `git push` commits with such signatures. -* In revsets, the working-copy or remote symbols (such as `@`, `workspace_id@`, +- In revsets, the working-copy or remote symbols (such as `@`, `workspace_id@`, and `branch@remote`) can no longer be quoted as a unit. If a workspace or branch name contains whitespace, quote the name like `"branch name"@remote`. Also, these symbols will not be resolved as revset aliases or function parameters. For example, `author(foo@)` is now an error, and the revset alias `'revset-aliases.foo@' = '@'` will be failed to parse. -* The `root` revset symbol has been converted to function `root()`. +- The `root` revset symbol has been converted to function `root()`. -* The `..x` revset is now evaluated to `root()..x`, which means the root commit +- The `..x` revset is now evaluated to `root()..x`, which means the root commit is no longer included. -* `jj git push` will now push all branches in the range `remote_branches()..@` +- `jj git push` will now push all branches in the range `remote_branches()..@` instead of only branches pointing to `@` or `@-`. -* It's no longer allowed to create a Git remote named "git". Use `jj git remote - rename` to rename the existing remote. +- It's no longer allowed to create a Git remote named "git". Use `jj git remote +rename` to rename the existing remote. [#1690](https://github.com/martinvonz/jj/issues/1690) -* Revset expression like `origin/main` will no longer resolve to a +- Revset expression like `origin/main` will no longer resolve to a remote-tracking branch. Use `main@origin` instead. ### New features -* Default template for `jj log` now does not show irrelevant information +- Default template for `jj log` now does not show irrelevant information (timestamp, empty, message placeholder etc.) about the root commit. -* Commit templates now support the `root` keyword, which is `true` for the root +- Commit templates now support the `root` keyword, which is `true` for the root commit and `false` for every other commit. -* `jj init --git-repo` now works with bare repositories. +- `jj init --git-repo` now works with bare repositories. -* `jj config edit --user` and `jj config set --user` will now pick a default +- `jj config edit --user` and `jj config set --user` will now pick a default config location if no existing file is found, potentially creating parent directories. -* `jj log` output is now topologically grouped. +- `jj log` output is now topologically grouped. [#242](https://github.com/martinvonz/jj/issues/242) -* `jj git clone` now supports the `--colocate` flag to create the git repo +- `jj git clone` now supports the `--colocate` flag to create the git repo in the same directory as the jj repo. -* `jj restore` gained a new option `--changes-in` to restore files +- `jj restore` gained a new option `--changes-in` to restore files from a merge revision's parents. This undoes the changes that `jj diff -r` would show. -* `jj diff`/`log` now supports `--tool ` option to generate diffs by +- `jj diff`/`log` now supports `--tool ` option to generate diffs by external program. For configuration, see [the documentation](docs/config.md). [#1886](https://github.com/martinvonz/jj/issues/1886) -* A new experimental diff editor `meld-3` is introduced that sets up Meld to +- A new experimental diff editor `meld-3` is introduced that sets up Meld to allow you to see both sides of the original diff while editing. This can be used with `jj split`, `jj move -i`, etc. -* `jj log`/`obslog`/`op log` now supports `--limit N` option to show the first +- `jj log`/`obslog`/`op log` now supports `--limit N` option to show the first `N` entries. -* Added the `ui.paginate` option to enable/disable pager usage in commands +- Added the `ui.paginate` option to enable/disable pager usage in commands -* `jj checkout`/`jj describe`/`jj commit`/`jj new`/`jj squash` can take repeated +- `jj checkout`/`jj describe`/`jj commit`/`jj new`/`jj squash` can take repeated `-m/--message` arguments. Each passed message will be combined into paragraphs (separated by a blank line) -* It is now possible to set a default description using the new +- It is now possible to set a default description using the new `ui.default-description` option, to use when describing changes with an empty description. -* `jj split` will now leave the description empty on the second part if the +- `jj split` will now leave the description empty on the second part if the description was empty on the input commit. -* `branches()`/`remote_branches()`/`author()`/`committer()`/`description()` +- `branches()`/`remote_branches()`/`author()`/`committer()`/`description()` revsets now support exact matching. For example, `branch(exact:main)` selects the branch named "main", but not "maint". `description(exact:"")` selects commits whose description is empty. -* Revsets gained a new function `mine()` that aliases `author(exact:"your_email")`. +- Revsets gained a new function `mine()` that aliases `author(exact:"your_email")`. -* Added support for `::` and `..` revset operators with both left and right +- Added support for `::` and `..` revset operators with both left and right operands omitted. These expressions are equivalent to `all()` and `~root()` respectively. -* `jj log` timestamp format now accepts `.utc()` to convert a timestamp to UTC. +- `jj log` timestamp format now accepts `.utc()` to convert a timestamp to UTC. -* templates now support additional string methods `.starts_with(x)`, `.ends_with(x)` +- templates now support additional string methods `.starts_with(x)`, `.ends_with(x)` `.remove_prefix(x)`, `.remove_suffix(x)`, and `.substr(start, end)`. -* `jj next` and `jj prev` are added, these allow you to traverse the history +- `jj next` and `jj prev` are added, these allow you to traverse the history in a linear style. For people coming from Sapling and `git-branchles` see [#2126](https://github.com/martinvonz/jj/issues/2126) for further pending improvements. -* `jj diff --stat` has been implemented. It shows a histogram of the changes, +- `jj diff --stat` has been implemented. It shows a histogram of the changes, same as `git diff --stat`. Fixes [#2066](https://github.com/martinvonz/jj/issues/2066) -* `jj git fetch --all-remotes` has been implemented. It fetches all remotes +- `jj git fetch --all-remotes` has been implemented. It fetches all remotes instead of just the default remote ### Fixed bugs -* Fix issues related to .gitignore handling of untracked directories +- Fix issues related to .gitignore handling of untracked directories [#2051](https://github.com/martinvonz/jj/issues/2051). -* `jj config set --user` and `jj config edit --user` can now be used outside of any repository. +- `jj config set --user` and `jj config edit --user` can now be used outside of any repository. -* SSH authentication could hang when ssh-agent couldn't be reached +- SSH authentication could hang when ssh-agent couldn't be reached [#1970](https://github.com/martinvonz/jj/issues/1970) -* SSH authentication can now use ed25519 and ed25519-sk keys. They still need +- SSH authentication can now use ed25519 and ed25519-sk keys. They still need to be password-less. -* Git repository managed by the repo tool can now be detected as a "colocated" +- Git repository managed by the repo tool can now be detected as a "colocated" repository. [#2011](https://github.com/martinvonz/jj/issues/2011) @@ -933,206 +927,205 @@ Thanks to the people who made this release happen! Thanks to the people who made this release happen! -* Alexander Potashev (@aspotashev) -* Anton Bulakh (@necauqua) -* Austin Seipp (@thoughtpolice) -* Benjamin Brittain (@benbrittain) -* Benjamin Saunders (@Ralith) -* Christophe Poucet (@poucet) -* Emily Kyle Fox (@emilykfox) -* Glen Choo (@chooglen) -* Ilya Grigoriev (@ilyagr) -* Kevin Liao (@kevincliao) -* Linus Arver (@listx) -* Martin Clausen (@maacl) -* Martin von Zweigbergk (@martinvonz) -* Matt Freitas-Stavola (@mbStavola) -* Oscar Bonilla (@ob) -* Philip Metzger (@PhilipMetzger) -* Piotr Kufel (@qfel) -* Preston Van Loon (@prestonvanloon) -* Tal Pressman (@talpr) -* Vamsi Avula (@avamsi) -* Vincent Breitmoser (@Valodim) -* Vladimir (@0xdeafbeef) -* Waleed Khan (@arxanas) -* Yuya Nishihara (@yuja) -* Zachary Dremann (@Dr-Emann) - +- Alexander Potashev (@aspotashev) +- Anton Bulakh (@necauqua) +- Austin Seipp (@thoughtpolice) +- Benjamin Brittain (@benbrittain) +- Benjamin Saunders (@Ralith) +- Christophe Poucet (@poucet) +- Emily Kyle Fox (@emilykfox) +- Glen Choo (@chooglen) +- Ilya Grigoriev (@ilyagr) +- Kevin Liao (@kevincliao) +- Linus Arver (@listx) +- Martin Clausen (@maacl) +- Martin von Zweigbergk (@martinvonz) +- Matt Freitas-Stavola (@mbStavola) +- Oscar Bonilla (@ob) +- Philip Metzger (@PhilipMetzger) +- Piotr Kufel (@qfel) +- Preston Van Loon (@prestonvanloon) +- Tal Pressman (@talpr) +- Vamsi Avula (@avamsi) +- Vincent Breitmoser (@Valodim) +- Vladimir (@0xdeafbeef) +- Waleed Khan (@arxanas) +- Yuya Nishihara (@yuja) +- Zachary Dremann (@Dr-Emann) ## [0.8.0] - 2023-07-09 ### Breaking changes -* The `jujutsu` and `jujutsu-lib` crates were renamed to `jj-cli` and `jj-lib`, +- The `jujutsu` and `jujutsu-lib` crates were renamed to `jj-cli` and `jj-lib`, respectively. -* The `ui.oplog-relative-timestamps` option has been removed. Use the +- The `ui.oplog-relative-timestamps` option has been removed. Use the `format_time_range()` template alias instead. For details, see [the documentation](docs/config.md). -* Implicit concatenation of template expressions has been disabled. Use +- Implicit concatenation of template expressions has been disabled. Use `++` operator, `concat()`, or `separate()` function instead. Example: `description ++ "\n"` -* `jj git push` will consider pushing the parent commit only when the +- `jj git push` will consider pushing the parent commit only when the current commit has no content and no description, such as right after a `jj squash`. -* The minimum supported Rust version (MSRV) is now 1.64.0. +- The minimum supported Rust version (MSRV) is now 1.64.0. -* The `heads()` revset function was split up into two functions. `heads()` +- The `heads()` revset function was split up into two functions. `heads()` without arguments is now called `visible_heads()`. `heads()` with one argument is unchanged. -* The `ui.default-revset` config was renamed to `revsets.log`. +- The `ui.default-revset` config was renamed to `revsets.log`. -* The `jj sparse` command was split up into `jj sparse list` and +- The `jj sparse` command was split up into `jj sparse list` and `jj sparse set`. -* `jj hide` (alias for `jj abandon`) is no longer available. Use `jj abandon` +- `jj hide` (alias for `jj abandon`) is no longer available. Use `jj abandon` instead. -* `jj debug completion`, `jj debug mangen` and `jj debug config-schema` have +- `jj debug completion`, `jj debug mangen` and `jj debug config-schema` have been moved from `jj debug` to `jj util`. -* `jj` will no longer parse `br` as a git_ref `refs/heads/br` when a branch `br` +- `jj` will no longer parse `br` as a git_ref `refs/heads/br` when a branch `br` does not exist but the git_ref does (this is rare). Use `br@git` instead. -* `jj git fetch` will no longer import unrelated branches from the underlying +- `jj git fetch` will no longer import unrelated branches from the underlying Git repo. ### New features -* `jj git push --deleted` will remove all locally deleted branches from the remote. +- `jj git push --deleted` will remove all locally deleted branches from the remote. -* `jj restore` without `--from` works correctly even if `@` is a merge +- `jj restore` without `--from` works correctly even if `@` is a merge commit. -* `jj rebase` now accepts multiple `-s` and `-b` arguments. Revsets with +- `jj rebase` now accepts multiple `-s` and `-b` arguments. Revsets with multiple commits are allowed with `--allow-large-revsets`. -* `jj git fetch` now supports a `--branch` argument to fetch some of the +- `jj git fetch` now supports a `--branch` argument to fetch some of the branches only. -* `jj config get` command allows retrieving config values for use in scripting. +- `jj config get` command allows retrieving config values for use in scripting. -* `jj config set` command allows simple config edits like +- `jj config set` command allows simple config edits like `jj config set --repo user.email "somebody@example.com"` -* Added `ui.log-word-wrap` option to wrap `jj log`/`obslog`/`op log` content +- Added `ui.log-word-wrap` option to wrap `jj log`/`obslog`/`op log` content based on terminal width. [#1043](https://github.com/martinvonz/jj/issues/1043) -* Nodes in the (text-based) graphical log output now use a `◉` symbol instead +- Nodes in the (text-based) graphical log output now use a `◉` symbol instead of the letter `o`. The ASCII-based graph styles still use `o`. -* Commands that accept a diff format (`jj diff`, `jj interdiff`, `jj show`, +- Commands that accept a diff format (`jj diff`, `jj interdiff`, `jj show`, `jj log`, and `jj obslog`) now accept `--types` to show only the type of file before and after. -* `jj describe` now supports `--reset-author` for resetting a commit's author +- `jj describe` now supports `--reset-author` for resetting a commit's author to the configured user. `jj describe` also gained a `--no-edit` option to avoid opening the editor. -* Added `latest(x[, n])` revset function to select the latest `n` commits. +- Added `latest(x[, n])` revset function to select the latest `n` commits. -* Added `conflict()` revset function to select commits with conflicts. +- Added `conflict()` revset function to select commits with conflicts. -* `jj squash` AKA `jj amend` now accepts a `--message` option to set the +- `jj squash` AKA `jj amend` now accepts a `--message` option to set the description of the squashed commit on the command-line. -* The progress display on `jj git clone/fetch` now includes the downloaded size. +- The progress display on `jj git clone/fetch` now includes the downloaded size. -* The formatter now supports a "default" color that can override another color +- The formatter now supports a "default" color that can override another color defined by a parent style. -* `jj obslog` and `jj log` now show abandoned commits as hidden. +- `jj obslog` and `jj log` now show abandoned commits as hidden. -* `jj git fetch` and `jj git push` will now use the single defined remote even +- `jj git fetch` and `jj git push` will now use the single defined remote even if it is not named "origin". -* `jj git push` now accepts `--branch` and `--change` arguments together. +- `jj git push` now accepts `--branch` and `--change` arguments together. -* `jj git push` now accepts a `-r/--revisions` flag to specify revisions to +- `jj git push` now accepts a `-r/--revisions` flag to specify revisions to push. All branches pointing to any of the specified revisions will be pushed. The flag can be used together with `--branch` and `--change`. -* `jj` with no subcommand now defaults to `jj log` instead of showing help. This +- `jj` with no subcommand now defaults to `jj log` instead of showing help. This command can be overridden by setting `ui.default-command`. -* Description tempfiles created via `jj describe` now have the file extension +- Description tempfiles created via `jj describe` now have the file extension `.jjdescription` to help external tooling detect a unique filetype. -* The shortest unique change ID prefixes and commit ID prefixes in `jj log` are +- The shortest unique change ID prefixes and commit ID prefixes in `jj log` are now shorter within the default log revset. You can override the default by setting the `revsets.short-prefixes` config to a different revset. -* The last seen state of branches in the underlying git repo is now presented by +- The last seen state of branches in the underlying git repo is now presented by `jj branch list`/`jj log` as a remote called `git` (e.g. `main@git`). They can also be referenced in revsets. Such branches exist in colocated repos or if you use `jj git export`. -* The new `jj chmod` command allows setting or removing the executable bit on +- The new `jj chmod` command allows setting or removing the executable bit on paths. Unlike the POSIX `chmod`, it works on Windows, on conflicted files, and on arbitrary revisions. Bits other than the executable bit are not planned to be supported. -* `jj sparse set` now accepts an `--edit` flag which brings up the `$EDITOR` to +- `jj sparse set` now accepts an `--edit` flag which brings up the `$EDITOR` to edit sparse patterns. -* `jj branch list` can now be filtered by revset. +- `jj branch list` can now be filtered by revset. -* Initial support for the Watchman filesystem monitor. Set +- Initial support for the Watchman filesystem monitor. Set `core.fsmonitor = "watchman"` in your repo to enable. ### Fixed bugs -* Modify/delete conflicts now include context lines +- Modify/delete conflicts now include context lines [#1244](https://github.com/martinvonz/jj/issues/1244). -* It is now possible to modify either side of a modify/delete conflict (any +- It is now possible to modify either side of a modify/delete conflict (any change used to be considered a resolution). -* Fixed a bug that could get partially resolved conflicts to be interpreted +- Fixed a bug that could get partially resolved conflicts to be interpreted incorrectly. -* `jj git fetch`: when re-adding a remote repository that had been previously +- `jj git fetch`: when re-adding a remote repository that had been previously removed, in some situations the remote branches were not recreated. -* `jj git remote rename`: the git remote references were not rewritten with +- `jj git remote rename`: the git remote references were not rewritten with the new name. If a new remote with the old name and containing the same branches was added, the remote branches may not be recreated in some cases. -* `jj workspace update-stale` now snapshots the working-copy changes before +- `jj workspace update-stale` now snapshots the working-copy changes before updating to the new working-copy commit. -* It is no longer allowed to create branches at the root commit. +- It is no longer allowed to create branches at the root commit. -* `git checkout` (without using `jj`) in colocated repo no longer abandons +- `git checkout` (without using `jj`) in colocated repo no longer abandons the previously checked-out anonymous branch. [#1042](https://github.com/martinvonz/jj/issues/1042). -* `jj git fetch` in a colocated repo now abandons branches deleted on the +- `jj git fetch` in a colocated repo now abandons branches deleted on the remote, just like in a non-colocated repo. [#864](https://github.com/martinvonz/jj/issues/864) -* `jj git fetch` can now fetch forgotten branches even if they didn't move on +- `jj git fetch` can now fetch forgotten branches even if they didn't move on the remote. [#1714](https://github.com/martinvonz/jj/pull/1714) [#1771](https://github.com/martinvonz/jj/pull/1771) -* It is now possible to `jj branch forget` deleted branches. +- It is now possible to `jj branch forget` deleted branches. [#1537](https://github.com/martinvonz/jj/issues/1537) -* Fixed race condition when assigning change id to Git commit. If you've +- Fixed race condition when assigning change id to Git commit. If you've already had unreachable change ids, run `jj debug reindex`. [#924](https://github.com/martinvonz/jj/issues/924) -* Fixed false divergence on racy working-copy snapshots. +- Fixed false divergence on racy working-copy snapshots. [#697](https://github.com/martinvonz/jj/issues/697), [#1608](https://github.com/martinvonz/jj/issues/1608) -* In colocated repos, a bug causing conflicts when undoing branch moves (#922) +- In colocated repos, a bug causing conflicts when undoing branch moves (#922) has been fixed. Some surprising behaviors related to undoing `jj git push` or `jj git fetch` remain. @@ -1140,83 +1133,82 @@ Thanks to the people who made this release happen! Thanks to the people who made this release happen! -* Aaron Bull Schaefer (@elasticdog) -* Anton Bulakh (@necauqua) -* Austin Seipp (@thoughtpolice) -* Benjamin Saunders (@Ralith) -* B Wilson (@xelxebar) -* Christophe Poucet (@poucet) -* David Barnett (@dbarnett) -* Glen Choo (@chooglen) -* Grégoire Geis (@71) -* Ilya Grigoriev (@ilyagr) -* Isabella Basso (@isinyaaa) -* Kevin Liao (@kevincliao) -* Martin von Zweigbergk (@martinvonz) -* mlcui (@mlcui-google) -* Samuel Tardieu (@samueltardieu) -* Tal Pressman (@talpr) -* Vamsi Avula (@avamsi) -* Waleed Khan (@arxanas) -* Yuya Nishihara (@yuja) - +- Aaron Bull Schaefer (@elasticdog) +- Anton Bulakh (@necauqua) +- Austin Seipp (@thoughtpolice) +- Benjamin Saunders (@Ralith) +- B Wilson (@xelxebar) +- Christophe Poucet (@poucet) +- David Barnett (@dbarnett) +- Glen Choo (@chooglen) +- Grégoire Geis (@71) +- Ilya Grigoriev (@ilyagr) +- Isabella Basso (@isinyaaa) +- Kevin Liao (@kevincliao) +- Martin von Zweigbergk (@martinvonz) +- mlcui (@mlcui-google) +- Samuel Tardieu (@samueltardieu) +- Tal Pressman (@talpr) +- Vamsi Avula (@avamsi) +- Waleed Khan (@arxanas) +- Yuya Nishihara (@yuja) ## [0.7.0] - 2023-02-16 ### Breaking changes -* The minimum supported Rust version (MSRV) is now 1.61.0. +- The minimum supported Rust version (MSRV) is now 1.61.0. -* The `jj touchup` command was renamed to `jj diffedit`. +- The `jj touchup` command was renamed to `jj diffedit`. -* The `-i` option to `jj restore` was removed in favor of new `--from`/`--to` +- The `-i` option to `jj restore` was removed in favor of new `--from`/`--to` options to `jj diffedit`. -* To report the situation when a change id corresponds to multiple visible +- To report the situation when a change id corresponds to multiple visible commits, `jj log` now prints the change id in red and puts `??` after it. Previously, it printed the word "divergent". -* `jj log` prefixes commit descriptions with "(empty)" when they contain no +- `jj log` prefixes commit descriptions with "(empty)" when they contain no change compared to their parents. -* The `author`/`committer` templates now display both name and email. Use +- The `author`/`committer` templates now display both name and email. Use `author.name()`/`committer.name()` to extract the name. -* Storage of the "HEAD@git" reference changed and can now have conflicts. +- Storage of the "HEAD@git" reference changed and can now have conflicts. Operations written by a new `jj` binary will have a "HEAD@git" reference that is not visible to older binaries. -* The `description` template keyword is now empty if no description set. +- The `description` template keyword is now empty if no description set. Use `if(description, description, "(no description set)\n")` to get back the previous behavior. -* The `template.log.graph` and `template.commit_summary` config keys were +- The `template.log.graph` and `template.commit_summary` config keys were renamed to `templates.log` and `templates.commit_summary` respectively. -* If a custom `templates.log` template is set, working-copy commit will +- If a custom `templates.log` template is set, working-copy commit will no longer be highlighted automatically. Wrap your template with `label(if(current_working_copy, "working_copy"), ...)` to label the working-copy entry. -* The `ui.relative-timestamps` option has been removed. Use the +- The `ui.relative-timestamps` option has been removed. Use the `format_timestamp()` template alias instead. For details on showing relative timestamps in `jj log` and `jj show`, see [the documentation](docs/config.md). -* `jj op log` now shows relative timestamps by default. To disable, set +- `jj op log` now shows relative timestamps by default. To disable, set `ui.oplog-relative-timestamps` to `false`. -* The global `--no-commit-working-copy` is now called `--ignore-working-copy`. +- The global `--no-commit-working-copy` is now called `--ignore-working-copy`. -* The `diff.format` config option is now called `ui.diff.format`. The old name +- The `diff.format` config option is now called `ui.diff.format`. The old name is still supported for now. -* `merge-tools..edit-args` now requires `$left`/`$right` parameters. +- `merge-tools..edit-args` now requires `$left`/`$right` parameters. The default is `edit-args = ["$left", "$right"]`. -* The builtin `jj update` and `jj up` aliases for `jj checkout` have been +- The builtin `jj update` and `jj up` aliases for `jj checkout` have been deleted. -* Change IDs are now rendered using letters from the end of the alphabet (from +- Change IDs are now rendered using letters from the end of the alphabet (from 'z' through 'k') instead of the usual hex digits ('0' through '9' and 'a' through 'f'). This is to clarify the distinction between change IDs and commit IDs, and to allow more efficient lookup of unique prefixes. This change @@ -1224,157 +1216,157 @@ Thanks to the people who made this release happen! ### New features -* The default log format now uses the committer timestamp instead of the author +- The default log format now uses the committer timestamp instead of the author timestamp. -* `jj log --summary --patch` now shows both summary and diff outputs. +- `jj log --summary --patch` now shows both summary and diff outputs. -* `jj git push` now accepts multiple `--branch`/`--change` arguments +- `jj git push` now accepts multiple `--branch`/`--change` arguments -* `jj config list` command prints values from config and `config edit` opens +- `jj config list` command prints values from config and `config edit` opens the config in an editor. -* `jj debug config-schema` command prints out JSON schema for the jj TOML config +- `jj debug config-schema` command prints out JSON schema for the jj TOML config file format. -* `jj resolve --list` can now describe the complexity of conflicts. +- `jj resolve --list` can now describe the complexity of conflicts. -* `jj resolve` now notifies the user of remaining conflicts, if any, on success. +- `jj resolve` now notifies the user of remaining conflicts, if any, on success. This can be prevented by the new `--quiet` option. -* Per-repository configuration is now read from `.jj/repo/config.toml`. +- Per-repository configuration is now read from `.jj/repo/config.toml`. -* Background colors, bold text, and underlining are now supported. You can set +- Background colors, bold text, and underlining are now supported. You can set e.g. `color.error = { bg = "red", bold = true, underline = true }` in your `~/.jjconfig.toml`. -* The `empty` condition in templates is true when the commit makes no change to +- The `empty` condition in templates is true when the commit makes no change to the three compared to its parents. -* `branches([needle])` revset function now takes `needle` as an optional +- `branches([needle])` revset function now takes `needle` as an optional argument and matches just the branches whose name contains `needle`. -* `remote_branches([branch_needle[, remote_needle]])` now takes `branch_needle` +- `remote_branches([branch_needle[, remote_needle]])` now takes `branch_needle` and `remote_needle` as optional arguments and matches just the branches whose name contains `branch_needle` and remote contains `remote_needle`. -* `jj git fetch` accepts repeated `--remote` arguments. +- `jj git fetch` accepts repeated `--remote` arguments. -* Default remotes can be configured for the `jj git fetch` and `jj git push` +- Default remotes can be configured for the `jj git fetch` and `jj git push` operations ("origin" by default) using the `git.fetch` and `git.push` configuration entries. `git.fetch` can be a list if multiple remotes must be fetched from. -* `jj duplicate` can now duplicate multiple changes in one go. This preserves +- `jj duplicate` can now duplicate multiple changes in one go. This preserves any parent-child relationships between them. For example, the entire tree of descendants of `abc` can be duplicated with `jj duplicate abc:`. -* `jj log` now highlights the shortest unique prefix of every commit and change +- `jj log` now highlights the shortest unique prefix of every commit and change id and shows the rest in gray. To customize the length and style, use the `format_short_id()` template alias. For details, see [the documentation](docs/config.md). -* `jj print` was renamed to `jj cat`. `jj print` remains as an alias. +- `jj print` was renamed to `jj cat`. `jj print` remains as an alias. -* In content that goes to the terminal, the ANSI escape byte (0x1b) is replaced +- In content that goes to the terminal, the ANSI escape byte (0x1b) is replaced by a "␛" character. That prevents them from interfering with the ANSI escapes jj itself writes. -* `jj workspace root` prints the root path of the current workspace. +- `jj workspace root` prints the root path of the current workspace. -* The `[alias]` config section was renamed to `[aliases]`. The old name is +- The `[alias]` config section was renamed to `[aliases]`. The old name is still accepted for backwards compatibility for some time. -* Commands that draw an ASCII graph (`jj log`, `jj op log`, `jj obslog`) now +- Commands that draw an ASCII graph (`jj log`, `jj op log`, `jj obslog`) now have different styles available by setting e.g. `ui.graph.style = "curved"`. -* `jj split` accepts creating empty commits when given a path. `jj split .` +- `jj split` accepts creating empty commits when given a path. `jj split .` inserts an empty commit between the target commit and its children if any, and `jj split any-non-existent-path` inserts an empty commit between the target commit and its parents. -* Command arguments to `ui.diff-editor`/`ui.merge-editor` can now be specified +- Command arguments to `ui.diff-editor`/`ui.merge-editor` can now be specified inline without referring to `[merge-tools]` table. -* `jj rebase` now accepts a new `--allow-large-revsets` argument that allows the +- `jj rebase` now accepts a new `--allow-large-revsets` argument that allows the revset in the `-d` argument to expand to several revisions. For example, `jj rebase -s B -d B- -d C` now works even if `B` is a merge commit. -* `jj new` now also accepts a `--allow-large-revsets` argument that behaves +- `jj new` now also accepts a `--allow-large-revsets` argument that behaves similarly to `jj rebase --allow-large-revsets`. -* `jj new --insert-before` inserts the new commit between the target commit and +- `jj new --insert-before` inserts the new commit between the target commit and its parents. -* `jj new --insert-after` inserts the new commit between the target commit and +- `jj new --insert-after` inserts the new commit between the target commit and its children. -* `author`/`committer` templates now support `.username()`, which leaves out the +- `author`/`committer` templates now support `.username()`, which leaves out the domain information of `.email()`. -* It is now possible to change the author format of `jj log` with the +- It is now possible to change the author format of `jj log` with the `format_short_signature()` template alias. For details, see [the documentation](docs/config.md). -* Added support for template aliases. New symbols and functions can be +- Added support for template aliases. New symbols and functions can be configured by `template-aliases. = `. Be aware that the template syntax isn't documented yet and is likely to change. -* The `ui.diff-instructions` config setting can be set to `false` to inhibit the +- The `ui.diff-instructions` config setting can be set to `false` to inhibit the creation of the `JJ-INSTRUCTIONS` file as part of diff editing. ### Fixed bugs -* When sharing the working copy with a Git repo, we used to forget to export +- When sharing the working copy with a Git repo, we used to forget to export branches to Git when only the working copy had changed. That's now fixed. -* Commit description set by `-m`/`--message` is now terminated with a newline +- Commit description set by `-m`/`--message` is now terminated with a newline character, just like descriptions set by editor are. -* The `-R`/`--repository` path must be a valid workspace directory. Its +- The `-R`/`--repository` path must be a valid workspace directory. Its ancestor directories are no longer searched. -* Fixed a crash when trying to access a commit that's never been imported into +- Fixed a crash when trying to access a commit that's never been imported into the jj repo from a Git repo. They will now be considered as non-existent if referenced explicitly instead of crashing. -* Fixed handling of escaped characters in .gitignore (only keep trailing spaces +- Fixed handling of escaped characters in .gitignore (only keep trailing spaces if escaped properly). -* `jj undo` now works after `jj duplicate`. +- `jj undo` now works after `jj duplicate`. -* `jj duplicate` followed by `jj rebase` of a tree containing both the original +- `jj duplicate` followed by `jj rebase` of a tree containing both the original and duplicate commit no longer crashes. The fix should also resolve any remaining instances of https://github.com/martinvonz/jj/issues/27. -* Fix the output of `jj debug completion --help` by reversing fish and zsh text. +- Fix the output of `jj debug completion --help` by reversing fish and zsh text. -* Fixed edge case in `jj git fetch` when a pruned branch is a prefix of another +- Fixed edge case in `jj git fetch` when a pruned branch is a prefix of another branch. ### Contributors Thanks to the people who made this release happen! - * Aleksandr Mikhailov (@AM5800) - * Augie Fackler (@durin42) - * Benjamin Saunders (@Ralith) - * Daniel Ploch (@torquestomp) - * Danny Hooper (@hooper) - * David Barnett (@dbarnett) - * Glen Choo (@chooglen) - * Herby Gillot (@herbygillot) - * Ilya Grigoriev (@ilyagr) - * Luke Granger-Brown (@lukegb) - * Martin von Zweigbergk (@martinvonz) - * Michael Forster (@MForster) - * Philip Metzger (@PhilipMetzger) - * Ruben Slabbert (@rslabbert) - * Samuel Tardieu (@samueltardieu) - * Tal Pressman (@talpr) - * Vamsi Avula (@avamsi) - * Waleed Khan (@arxanas) - * Yuya Nishihara (@yuja) +- Aleksandr Mikhailov (@AM5800) +- Augie Fackler (@durin42) +- Benjamin Saunders (@Ralith) +- Daniel Ploch (@torquestomp) +- Danny Hooper (@hooper) +- David Barnett (@dbarnett) +- Glen Choo (@chooglen) +- Herby Gillot (@herbygillot) +- Ilya Grigoriev (@ilyagr) +- Luke Granger-Brown (@lukegb) +- Martin von Zweigbergk (@martinvonz) +- Michael Forster (@MForster) +- Philip Metzger (@PhilipMetzger) +- Ruben Slabbert (@rslabbert) +- Samuel Tardieu (@samueltardieu) +- Tal Pressman (@talpr) +- Vamsi Avula (@avamsi) +- Waleed Khan (@arxanas) +- Yuya Nishihara (@yuja) ## [0.6.1] - 2022-12-05 @@ -1384,23 +1376,23 @@ No changes, only changed to a released version of the `thrift` crate dependency. ### Breaking changes -* Dropped candidates set argument from `description(needle)`, `author(needle)`, +- Dropped candidates set argument from `description(needle)`, `author(needle)`, `committer(needle)`, `merges()` revsets. Use `x & description(needle)` instead. -* Adjusted precedence of revset union/intersection/difference operators. +- Adjusted precedence of revset union/intersection/difference operators. `x | y & z` is now equivalent to `x | (y & z)`. -* Support for open commits has been dropped. The `ui.enable-open-commits` config +- Support for open commits has been dropped. The `ui.enable-open-commits` config that was added in 0.5.0 is no longer respected. The `jj open/close` commands have been deleted. -* `jj commit` is now a separate command from `jj close` (which no longer +- `jj commit` is now a separate command from `jj close` (which no longer exists). The behavior has changed slightly. It now always asks for a description, even if there already was a description set. It now also only works on the working-copy commit (there's no `-r` argument). -* If a workspace's working-copy commit has been updated from another workspace, +- If a workspace's working-copy commit has been updated from another workspace, most commands in that workspace will now fail. Use the new `jj workspace update-stale` command to update the workspace to the new working-copy commit. (The old behavior was to automatically update the @@ -1408,90 +1400,90 @@ No changes, only changed to a released version of the `thrift` crate dependency. ### New features -* Commands with long output are paginated. +- Commands with long output are paginated. [#9](https://github.com/martinvonz/jj/issues/9) -* The new `jj git remote rename` command allows git remotes to be renamed +- The new `jj git remote rename` command allows git remotes to be renamed in-place. -* The new `jj resolve` command allows resolving simple conflicts with +- The new `jj resolve` command allows resolving simple conflicts with an external 3-way-merge tool. -* `jj git push` will search `@-` for branches to push if `@` has none. +- `jj git push` will search `@-` for branches to push if `@` has none. -* The new revset function `file(pattern..)` finds commits modifying the +- The new revset function `file(pattern..)` finds commits modifying the paths specified by the `pattern..`. -* The new revset function `empty()` finds commits modifying no files. +- The new revset function `empty()` finds commits modifying no files. -* Added support for revset aliases. New symbols and functions can be configured +- Added support for revset aliases. New symbols and functions can be configured by `revset-aliases. = `. -* It is now possible to specify configuration options on the command line +- It is now possible to specify configuration options on the command line with the new `--config-toml` global option. -* `jj git` subcommands will prompt for credentials when required for HTTPS +- `jj git` subcommands will prompt for credentials when required for HTTPS remotes rather than failing. [#469](https://github.com/martinvonz/jj/issues/469) -* Branches that have a different target on some remote than they do locally are +- Branches that have a different target on some remote than they do locally are now indicated by an asterisk suffix (e.g. `main*`) in `jj log`. [#254](https://github.com/martinvonz/jj/issues/254) -* The commit ID was moved from first on the line in `jj log` output to close to +- The commit ID was moved from first on the line in `jj log` output to close to the end. The goal is to encourage users to use the change ID instead, since that is generally more convenient, and it reduces the risk of creating divergent commits. -* The username and hostname that appear in the operation log are now +- The username and hostname that appear in the operation log are now configurable via config options `operation.username` and `operation.hostname`. -* `jj git` subcommands now support credential helpers. +- `jj git` subcommands now support credential helpers. -* `jj log` will warn if it appears that the provided path was meant to be a +- `jj log` will warn if it appears that the provided path was meant to be a revset. -* The new global flag `-v/--verbose` will turn on debug logging to give +- The new global flag `-v/--verbose` will turn on debug logging to give some additional insight into what is happening behind the scenes. Note: This is not comprehensively supported by all operations yet. -* `jj log`, `jj show`, and `jj obslog` now all support showing relative +- `jj log`, `jj show`, and `jj obslog` now all support showing relative timestamps by setting `ui.relative-timestamps = true` in the config file. ### Fixed bugs -* A bug in the export of branches to Git caused spurious conflicted branches. +- A bug in the export of branches to Git caused spurious conflicted branches. This typically occurred when running in a working copy colocated with Git (created by running `jj init --git-dir=.`). [#463](https://github.com/martinvonz/jj/issues/463) -* When exporting branches to Git, we used to fail if some branches could not be +- When exporting branches to Git, we used to fail if some branches could not be exported (e.g. because Git doesn't allow a branch called `main` and another branch called `main/sub`). We now print a warning about these branches instead. [#493](https://github.com/martinvonz/jj/issues/493) -* If you had modified branches in jj and also modified branches in conflicting +- If you had modified branches in jj and also modified branches in conflicting ways in Git, `jj git export` used to overwrite the changes you made in Git. We now print a warning about these branches instead. -* `jj edit root` now fails gracefully. +- `jj edit root` now fails gracefully. -* `jj git import` used to abandon a commit if Git branches and tags referring +- `jj git import` used to abandon a commit if Git branches and tags referring to it were removed. We now keep it if a detached HEAD refers to it. -* `jj git import` no longer crashes when all Git refs are removed. +- `jj git import` no longer crashes when all Git refs are removed. -* Git submodules are now ignored completely. Earlier, files present in the +- Git submodules are now ignored completely. Earlier, files present in the submodule directory in the working copy would become added (tracked), and later removed if you checked out another commit. You can now use `git` to populate the submodule directory and `jj` will leave it alone. -* Git's GC could remove commits that were referenced from jj in some cases. We +- Git's GC could remove commits that were referenced from jj in some cases. We are now better at adding Git refs to prevent that. [#815](https://github.com/martinvonz/jj/issues/815) -* When the working-copy commit was a merge, `jj status` would list only the +- When the working-copy commit was a merge, `jj status` would list only the first parent, and the diff summary would be against that parent. The output now lists all parents and the diff summary is against the auto-merged parents. @@ -1499,17 +1491,16 @@ No changes, only changed to a released version of the `thrift` crate dependency. Thanks to the people who made this release happen! - * Martin von Zweigbergk (@martinvonz) - * Benjamin Saunders (@Ralith) - * Yuya Nishihara (@yuja) - * Glen Choo (@chooglen) - * Ilya Grigoriev (@ilyagr) - * Ruben Slabbert (@rslabbert) - * Waleed Khan (@arxanas) - * Sean E. Russell (@xxxserxxx) - * Pranay Sashank (@pranaysashank) - * Luke Granger-Brown (@lukegb) - +- Martin von Zweigbergk (@martinvonz) +- Benjamin Saunders (@Ralith) +- Yuya Nishihara (@yuja) +- Glen Choo (@chooglen) +- Ilya Grigoriev (@ilyagr) +- Ruben Slabbert (@rslabbert) +- Waleed Khan (@arxanas) +- Sean E. Russell (@xxxserxxx) +- Pranay Sashank (@pranaysashank) +- Luke Granger-Brown (@lukegb) ## [0.5.1] - 2022-10-17 @@ -1519,210 +1510,210 @@ No changes (just trying to get automated GitHub release to work). ### Breaking changes -* Open commits are now disabled by default. That means that `jj checkout` will +- Open commits are now disabled by default. That means that `jj checkout` will always create a new change on top of the specified commit and will let you edit that in the working copy. Set `ui.enable-open-commits = true` to restore the old behavior and let us know that you did so we know how many people prefer the workflow with open commits. -* `jj [op] undo` and `jj op restore` used to take the operation to undo or +- `jj [op] undo` and `jj op restore` used to take the operation to undo or restore to as an argument to `-o/--operation`. It is now a positional argument instead (i.e. `jj undo -o abc123` is now written `jj undo abc123`). -* An alias that is not configured as a string list (e.g. `my-status = "status"` +- An alias that is not configured as a string list (e.g. `my-status = "status"` instead of `my-status = ["status"]`) is now an error instead of a warning. -* `jj log` now defaults to showing only commits that are not on any remote +- `jj log` now defaults to showing only commits that are not on any remote branches (plus their closest commit on the remote branch for context). This set of commits can be overridden by setting `ui.default-revset`. Use `jj log -r 'all()'` for the old behavior. Read more about revsets [here](https://github.com/martinvonz/jj/blob/main/docs/revsets.md). [#250](https://github.com/martinvonz/jj/issues/250) -* `jj new` now always checks out the new commit (used to be only if the parent +- `jj new` now always checks out the new commit (used to be only if the parent was `@`). -* `jj merge` now checks out the new commit. The command now behaves exactly +- `jj merge` now checks out the new commit. The command now behaves exactly like `jj new`, except that it requires at least two arguments. -* When the working-copy commit is abandoned by `jj abandon` and the parent +- When the working-copy commit is abandoned by `jj abandon` and the parent commit is open, a new working-copy commit will be created on top (the open parent commit used to get checked out). -* `jj branch` now uses subcommands like `jj branch create` and +- `jj branch` now uses subcommands like `jj branch create` and `jj branch forget` instead of options like `jj branch --forget`. [#330](https://github.com/martinvonz/jj/issues/330) -* The [`$NO_COLOR` environment variable](https://no-color.org/) no longer +- The [`$NO_COLOR` environment variable](https://no-color.org/) no longer overrides the `ui.color` configuration if explicitly set. -* `jj edit` has been renamed to `jj touchup`, and `jj edit` is now a new command +- `jj edit` has been renamed to `jj touchup`, and `jj edit` is now a new command with different behavior. The new `jj edit` lets you edit a commit in the working copy, even if the specified commit is closed. -* `jj git push` no longer aborts if you attempt to push an open commit (but it +- `jj git push` no longer aborts if you attempt to push an open commit (but it now aborts if a commit does not have a description). -* `jj git push` now pushes only branches pointing to the `@` by default. Use +- `jj git push` now pushes only branches pointing to the `@` by default. Use `--all` to push all branches. -* The `checkouts` template keyword is now called `working_copies`, and +- The `checkouts` template keyword is now called `working_copies`, and `current_checkout` is called `current_working_copy`. ### New features -* The new `jj interdiff` command compares the changes in commits, ignoring +- The new `jj interdiff` command compares the changes in commits, ignoring changes from intervening commits. -* `jj rebase` now accepts a `--branch/-b ` argument, which can be used +- `jj rebase` now accepts a `--branch/-b ` argument, which can be used instead of `-r` or `-s` to specify which commits to rebase. It will rebase the whole branch, relative to the destination. The default mode has changed from `-r @` to `-b @`. -* The new `jj print` command prints the contents of a file in a revision. +- The new `jj print` command prints the contents of a file in a revision. -* The new `jj git remotes list` command lists the configured remotes and their +- The new `jj git remotes list` command lists the configured remotes and their URLs. [#243](https://github.com/martinvonz/jj/issues/243) -* `jj move` and `jj squash` now lets you limit the set of changes to move by +- `jj move` and `jj squash` now lets you limit the set of changes to move by specifying paths on the command line (in addition to the `--interactive` mode). For example, use `jj move --to @-- foo` to move the changes to file (or directory) `foo` in the working copy to the grandparent commit. -* When `jj move/squash/unsquash` abandons the source commit because it became +- When `jj move/squash/unsquash` abandons the source commit because it became empty and both the source and the destination commits have non-empty descriptions, it now asks for a combined description. If either description was empty, it uses the other without asking. -* `jj split` now lets you specify on the CLI which paths to include in the first +- `jj split` now lets you specify on the CLI which paths to include in the first commit. The interactive diff-editing is not started when you do that. -* Sparse checkouts are now supported. In fact, all working copies are now +- Sparse checkouts are now supported. In fact, all working copies are now "sparse", only to different degrees. Use the `jj sparse` command to manage the paths included in the sparse checkout. -* Configuration is now also read from `~/.jjconfig.toml`. +- Configuration is now also read from `~/.jjconfig.toml`. -* The `$JJ_CONFIG` environment variable can now point to a directory. If it +- The `$JJ_CONFIG` environment variable can now point to a directory. If it does, all files in the directory will be read, in alphabetical order. -* The `$VISUAL` environment is now respected and overrides `$EDITOR`. The new +- The `$VISUAL` environment is now respected and overrides `$EDITOR`. The new `ui.editor` config has higher priority than both of them. There is also a new `$JJ_EDITOR` environment variable, which has even higher priority than the config. -* You can now use `-` and `+` in revset symbols. You used to have to quote +- You can now use `-` and `+` in revset symbols. You used to have to quote branch names like `my-feature` in nested quotes (outer layer for your shell) like `jj co '"my-feature"'`. The quoting is no longer needed. -* The new revset function `connected(x)` is the same as `x:x`. +- The new revset function `connected(x)` is the same as `x:x`. -* The new revset function `roots(x)` finds commits in the set that are not +- The new revset function `roots(x)` finds commits in the set that are not descendants of other commits in the set. -* ssh-agent is now detected even if `$SSH_AGENT_PID` is not set (as long as +- ssh-agent is now detected even if `$SSH_AGENT_PID` is not set (as long as `$SSH_AUTH_SOCK` is set). This should help at least macOS users where ssh-agent is launched by default and only `$SSH_AUTH_SOCK` is set. -* When importing from a git, any commits that are no longer referenced on the +- When importing from a git, any commits that are no longer referenced on the git side will now be abandoned on the jj side as well. That means that `jj git fetch` will now abandon unreferenced commits and rebase any local changes you had on top. -* `jj git push` gained a `--change ` argument. When that's used, it +- `jj git push` gained a `--change ` argument. When that's used, it will create a branch named after the revision's change ID, so you don't have to create a branch yourself. By default, the branch name will start with `push-`, but this can be overridden by the `push.branch-prefix` config setting. -* `jj git push` now aborts if you attempt to push a commit without a +- `jj git push` now aborts if you attempt to push a commit without a description or with the placeholder "(no name/email configured)" values for author/committer. -* Diff editor command arguments can now be specified by config file. +- Diff editor command arguments can now be specified by config file. Example: [merge-tools.kdiff3] program = "kdiff3" edit-args = ["--merge", "--cs", "CreateBakFiles=0"] -* `jj branch` can accept any number of branches to update, rather than just one. +- `jj branch` can accept any number of branches to update, rather than just one. -* Aliases can now call other aliases. +- Aliases can now call other aliases. -* `jj log` now accepts a `--reversed` option, which will show older commits +- `jj log` now accepts a `--reversed` option, which will show older commits first. -* `jj log` now accepts file paths. +- `jj log` now accepts file paths. -* `jj obslog` now accepts `-p`/`--patch` option, which will show the diff +- `jj obslog` now accepts `-p`/`--patch` option, which will show the diff compared to the previous version of the change. -* The "(no name/email configured)" placeholder value for name/email will now be +- The "(no name/email configured)" placeholder value for name/email will now be replaced if once you modify a commit after having configured your name/email. -* Color setting can now be overridden by `--color=always|never|auto` option. +- Color setting can now be overridden by `--color=always|never|auto` option. -* `jj checkout` now lets you specify a description with `--message/-m`. +- `jj checkout` now lets you specify a description with `--message/-m`. -* `jj new` can now be used for creating merge commits. If you pass more than +- `jj new` can now be used for creating merge commits. If you pass more than one argument to it, the new commit will have all of them as parents. ### Fixed bugs -* When rebasing a conflict where one side modified a file and the other side +- When rebasing a conflict where one side modified a file and the other side deleted it, we no longer automatically resolve it in favor of the modified content (this was a regression from commit c0ae4b16e8c4). -* Errors are now printed to stderr (they used to be printed to stdout). +- Errors are now printed to stderr (they used to be printed to stdout). -* Updating the working copy to a commit where a file's executable bit changed +- Updating the working copy to a commit where a file's executable bit changed but the contents was the same used to lead to a crash. That has now been fixed. -* If one side of a merge modified a directory and the other side deleted it, it +- If one side of a merge modified a directory and the other side deleted it, it used to be considered a conflict. The same was true if both sides added a directory with different files in. They are now merged as if the missing directory had been empty. -* When using `jj move` to move part of a commit into an ancestor, any branches +- When using `jj move` to move part of a commit into an ancestor, any branches pointing to the source commit used to be left on a hidden intermediate commit. They are now correctly updated. -* `jj untrack` now requires at least one path (allowing no arguments was a UX +- `jj untrack` now requires at least one path (allowing no arguments was a UX bug). -* `jj rebase` now requires at least one destination (allowing no arguments was a +- `jj rebase` now requires at least one destination (allowing no arguments was a UX bug). -* `jj restore --to ` now restores from the working copy (it used to restore +- `jj restore --to ` now restores from the working copy (it used to restore from the working copy's parent). -* You now get a proper error message instead of a crash when `$EDITOR` doesn't +- You now get a proper error message instead of a crash when `$EDITOR` doesn't exist or exits with an error. -* Global arguments, such as `--at-op=`, can now be passed before +- Global arguments, such as `--at-op=`, can now be passed before an alias. -* Fixed relative path to the current directory in output to be `.` instead of +- Fixed relative path to the current directory in output to be `.` instead of empty string. -* When adding a new workspace, the parent of the current workspace's current +- When adding a new workspace, the parent of the current workspace's current checkout will be checked out. That was always the intent, but the root commit was accidentally checked out instead. -* When checking out a commit, the previous commit is no longer abandoned if it +- When checking out a commit, the previous commit is no longer abandoned if it has a non-empty description. -* All commands now consistently snapshot the working copy (it was missing from +- All commands now consistently snapshot the working copy (it was missing from e.g. `jj undo` and `jj merge` before). ## [0.4.0] - 2022-04-02 ### Breaking changes -* Dropped support for config in `~/.jjconfig`. Your configuration is now read +- Dropped support for config in `~/.jjconfig`. Your configuration is now read from `/jj/config.toml`, where `` is `${XDG_CONFIG_HOME}` or `~/.config/` on Linux, `~/Library/Application Support/` on macOS, and `~\AppData\Roaming\` on @@ -1730,20 +1721,20 @@ No changes (just trying to get automated GitHub release to work). ### New features -* You can now set an environment variable called `$JJ_CONFIG` to a path to a +- You can now set an environment variable called `$JJ_CONFIG` to a path to a config file. That will then be read instead of your regular config file. This is mostly intended for testing and scripts. -* The [standard `$NO_COLOR` environment variable](https://no-color.org/) is now +- The [standard `$NO_COLOR` environment variable](https://no-color.org/) is now respected. -* `jj new` now lets you specify a description with `--message/-m`. +- `jj new` now lets you specify a description with `--message/-m`. -* When you check out a commit, the old commit no longer automatically gets +- When you check out a commit, the old commit no longer automatically gets abandoned if it's empty and has descendants, it only gets abandoned if it's empty and does not have descendants. -* When undoing an earlier operation, any new commits on top of commits from the +- When undoing an earlier operation, any new commits on top of commits from the undone operation will be rebased away. For example, let's say you rebase commit A so it becomes a new commit A', and then you create commit B on top of A'. If you now undo the rebase operation, commit B will be rebased to be on @@ -1753,13 +1744,13 @@ No changes (just trying to get automated GitHub release to work). A'). See #111 for more examples. [#111](https://github.com/martinvonz/jj/issues/111) -* `jj log` now accepts `-p`/`--patch` option. +- `jj log` now accepts `-p`/`--patch` option. ### Fixed bugs -* Fixed crash on `jj init --git-repo=.` (it almost always crashed). +- Fixed crash on `jj init --git-repo=.` (it almost always crashed). -* When sharing the working copy with a Git repo, the automatic importing and +- When sharing the working copy with a Git repo, the automatic importing and exporting (sometimes?) didn't happen on Windows. ## [0.3.3] - 2022-03-16 @@ -1774,9 +1765,9 @@ No changes, only trying to get the automated build to work. ### Fixed bugs - - Fixed crash when `core.excludesFile` pointed to nonexistent file, and made - leading `~/` in that config expand to `$HOME/` - [#131](https://github.com/martinvonz/jj/issues/131) +- Fixed crash when `core.excludesFile` pointed to nonexistent file, and made + leading `~/` in that config expand to `$HOME/` + [#131](https://github.com/martinvonz/jj/issues/131) ## [0.3.0] - 2022-03-12 diff --git a/README.md b/README.md index badedbb37d..995eecbf9e 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ experienced, working on brand new projects alone, or large scale software projects with large histories and teams. Jujutsu is unlike most other systems, because internally it abstracts the user -interface and version control algorithms from the *storage systems* used to +interface and version control algorithms from the _storage systems_ used to serve your content. This allows it to serve as a VCS with many possible physical backends, that may have their own data or networking models—like [Mercurial] or [Breezy], or hybrid systems like Google's cloud-based design, [Piper/CitC]. @@ -80,7 +80,7 @@ And it adds several innovative, useful features of its own: - **Operation log & undo**: Jujutsu records every operation that is performed on the repository, from commits, to pulls, to pushes. This makes debugging problems like - "what just happened?" or "how did I end up here?" easier, *especially* when + "what just happened?" or "how did I end up here?" easier, _especially_ when you're helping your coworker answer those questions about their repository! And because everything is recorded, you can undo that mistake you just made with ease. Version control has finally entered [the 1960s][undo-history]! @@ -90,7 +90,7 @@ And it adds several innovative, useful features of its own: makes "patch-based" workflows a breeze. If you resolve a conflict in a commit, the _resolution_ of that conflict is also propagated through descendants as well. In effect, this is a completely transparent version of `git rebase - --update-refs` combined with `git rerere`, supported by design. +--update-refs` combined with `git rerere`, supported by design. > [!WARNING] > The following features are available for use, but experimental; they may have @@ -102,14 +102,14 @@ And it adds several innovative, useful features of its own: The fundamental problem with using filesystems like Dropbox and backup tools like `rsync` on your typical Git/Mercurial repositories is that they rely - on *local filesystem operations* being atomic, serialized, and non-concurrent + on _local filesystem operations_ being atomic, serialized, and non-concurrent with respect to other reads and writes—which is _not_ true when operating on distributed file systems, or when operations like concurrent file copies (for backup) happen while lock files are being held. Jujutsu is instead designed to be [safe under concurrent scenarios][conc-safety]; simply using rsync or Dropbox and then using that resulting repository - should never result in a repository in a *corrupt state*. The worst that + should never result in a repository in a _corrupt state_. The worst that _should_ happen is that it will expose conflicts between the local and remote state, leaving you to resolve them. @@ -130,30 +130,30 @@ developers monitor both channels. ### News and Updates 📣 - **Feb 2024**: Version 0.14 is released, which deprecates ["jj checkout" and "jj merge"](CHANGELOG.md#deprecations-1), - as well as `jj init --git`, which is now just called `jj git init`. + as well as `jj init --git`, which is now just called `jj git init`. - **Oct 2023**: Version 0.10.0 is released! Now includes a bundled merge and diff editor for all platforms, "immutable revsets" to avoid accidentally `edit`-ing the wrong revisions, and lots of polish. - **Jan 2023**: Martin gave a presentation about Google's plans for Jujutsu at - Git Merge 2022! + Git Merge 2022! See the [slides][merge-slides] or the [recording][merge-talk]. ### Related Media - **Mar 2024**: Chris Krycho started [a YouTube series about Jujutsu][krycho-yt]. - **Feb 2024**: Chris Krycho published an article about Jujutsu called [jj init][krycho] - and Steve Klabnik followed up with the [Jujutsu Tutorial][klabnik]. -- **Jan 2024**: Jujutsu was featured in an LWN.net article called + and Steve Klabnik followed up with the [Jujutsu Tutorial][klabnik]. +- **Jan 2024**: Jujutsu was featured in an LWN.net article called [Jujutsu: a new, Git-compatible version control system][lwn]. -- **Jan 2023**: Martin's Talk about Jujutsu at Git Merge 2022, [video][merge-talk] +- **Jan 2023**: Martin's Talk about Jujutsu at Git Merge 2022, [video][merge-talk] and the associated [slides][merge-slides]. [krycho-yt]: https://www.youtube.com/playlist?list=PLelyiwKWHHAq01Pvmpf6x7J0y-yQpmtxp [krycho]: https://v5.chriskrycho.com/essays/jj-init/ [klabnik]: https://steveklabnik.github.io/jujutsu-tutorial/ -[lwn]: https://lwn.net/Articles/958468/ +[lwn]: https://lwn.net/Articles/958468/ [merge-talk]: https://www.youtube.com/watch?v=bx_LGilOuE4 -[merge-slides]: https://docs.google.com/presentation/d/1F8j9_UOOSGUN9MvHxPZX_L4bQ9NMcYOp1isn17kTC_M/view +[merge-slides]: https://docs.google.com/presentation/d/1F8j9_UOOSGUN9MvHxPZX_L4bQ9NMcYOp1isn17kTC_M/view ## Getting started @@ -194,16 +194,16 @@ while the other is a native storage backend[^native-backend]. [backends]: https://martinvonz.github.io/jj/latest/glossary#backend -[^native-backend]: At this time, there's practically no reason to use the native -backend. The backend exists mainly to make sure that it's possible to eventually -add functionality that cannot easily be added to the Git backend. +[^native-backend]: + At this time, there's practically no reason to use the native + backend. The backend exists mainly to make sure that it's possible to eventually + add functionality that cannot easily be added to the Git backend. The Git backend is fully featured and maintained, and allows you to use Jujutsu as an alternative interface to Git. The commits you create will look like regular Git commits. You can always switch back to Git. The Git support uses the [libgit2](https://libgit2.org/) C library. - You can even have a ["co-located" local @@ -292,7 +292,7 @@ have almost exclusively used `jj` to develop the project itself since early January 2021. I haven't had to re-clone from source (I don't think I've even had to restore from backup). -There *will* be changes to workflows and backward-incompatible changes to the +There _will_ be changes to workflows and backward-incompatible changes to the on-disk formats before version 1.0.0. Even the binary's name may change (i.e. away from `jj`). For any format changes, we'll try to implement transparent upgrades (as we've done with recent changes), or provide upgrade commands or diff --git a/cli/src/config/README.md b/cli/src/config/README.md index d51750e0a3..f9d1bd20f5 100644 --- a/cli/src/config/README.md +++ b/cli/src/config/README.md @@ -1,2 +1,2 @@ These files are compiled into the binary; they are not installed to the user's -system. \ No newline at end of file +system. diff --git a/demos/README.md b/demos/README.md index 46a70bcde7..58bdf8461e 100644 --- a/demos/README.md +++ b/demos/README.md @@ -26,7 +26,7 @@ One way to make all the images and check the output is: ```shell cd demos -./run_scripts.sh demo_*.sh |less +./run_scripts.sh demo_*.sh | less ``` ### A note on fonts diff --git a/docs/FAQ.md b/docs/FAQ.md index b4203eb71c..3686d83701 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -12,8 +12,8 @@ To move branches, use `jj branch set`. `jj git push --all` pushes all _branches_, not all revisions. You have two options: -* Using `jj git push --change` will automatically create a branch and push it. -* Using `jj branch` commands to create or move a branch to either the commit +- Using `jj git push --change` will automatically create a branch and push it. +- Using `jj branch` commands to create or move a branch to either the commit you want to push or a descendant on it. Unlike Git, Jujutsu doesn't do this automatically (see previous question). @@ -37,12 +37,12 @@ See [revsets] and [templates] for further guidance. Use `jj log -r ..`. The `..` [operator] lists all visible commits in the repo, excluding the root (which is never interesting and is shared by all repos). -### `jj` is said to record the working copy after `jj log` and every other command. Where can I see these automatic "saves"? +### `jj` is said to record the working copy after `jj log` and every other command. Where can I see these automatic "saves"? -Indeed, every `jj` command updates the current "working-copy" revision, marked +Indeed, every `jj` command updates the current "working-copy" revision, marked with `@` in `jj log`. You can notice this by how the [commit ID] of the working copy revision changes when it's updated. Note that, unless you move to -another revision (with `jj new` or `jj edit`, for example), the [change ID] will +another revision (with `jj new` or `jj edit`, for example), the [change ID] will not change. If you expected to see a historical view of your working copy changes in the @@ -139,7 +139,7 @@ commit to the new state. ### How do I resume working on an existing change? There are two ways to resume working on an earlier change: `jj new` then `jj squash`, -and `jj edit`. The first is generally recommended, but `jj edit` can be useful. When +and `jj edit`. The first is generally recommended, but `jj edit` can be useful. When you use `jj edit`, the revision is directly amended with your new changes, making it difficult to tell what exactly you change. You should avoid using `jj edit` when the revision has a conflict, as you may accidentally break the plain-text annotations on @@ -147,7 +147,7 @@ your state without realising. To start, use `jj new ` to create a change based on that earlier revision. Make your edits, then use `jj squash` to update the earlier revision with those edits. -For when you would use git stashing, use `jj edit ` for expected behaviour. +For when you would use git stashing, use `jj edit ` for expected behaviour. Other workflows may prefer `jj edit` as well. ### How do I deal with divergent changes ('??' after the [change ID])? @@ -193,21 +193,14 @@ directory. We hope to integrate with Gerrit natively in the future. [branches_conflicts]: branches.md#conflicts - [change ID]: glossary.md#change-id [co-located]: glossary.md#co-located-repos [commit ID]: glossary.md#commit-id [config]: config.md - [gerrit-integration]: https://gist.github.com/thoughtpolice/8f2fd36ae17cd11b8e7bd93a70e31ad6 [gitignore]: https://git-scm.com/docs/gitignore - [glossary_divergent_change]: glossary.md#divergent-change - [operator]: revsets.md#operators - [revsets]: revsets.md - [templates]: templates.md - [this issue]: https://github.com/martinvonz/jj/issues/1531 diff --git a/docs/branches.md b/docs/branches.md index ce38cc0ed0..06323266be 100644 --- a/docs/branches.md +++ b/docs/branches.md @@ -1,6 +1,5 @@ # Branches - ## Introduction Branches are named pointers to revisions (just like they are in Git). You can @@ -48,7 +47,7 @@ target there, `jj log` will show the branch name with an asterisk suffix (e.g. `main*`). That is meant to remind you that you may want to push the branch to some remote. -If you want to know the internals of branch tracking, consult the +If you want to know the internals of branch tracking, consult the [Design Doc][design]. ### Terminology summary @@ -63,7 +62,7 @@ If you want to know the internals of branch tracking, consult the example. - A **tracking (local) branch** is the local branch that `jj` tries to keep in sync with the tracked remote branch. For example, after `jj branch track - mybranch@origin`, there will be a local branch `mybranch` that's tracking the +mybranch@origin`, there will be a local branch `mybranch` that's tracking the remote `mybranch@origin` branch. A local branch can track a branch of the same name on 0 or more remotes. @@ -74,9 +73,9 @@ must match. ### Manually tracking a branch -To track a branch permanently use `jj branch track @`. +To track a branch permanently use `jj branch track @`. It will now be imported as a local branch until you untrack it or it is deleted -on the remote. +on the remote. Example: @@ -99,7 +98,7 @@ To stop following a remote branch, you can `jj branch untrack` it. After that, subsequent fetches of that remote will no longer move the local branch to match the position of the remote branch. -Example: +Example: ```sh $ # List all local and remote branches. @@ -120,7 +119,6 @@ This command omits local Git-tracking branches by default. You can see if a specific branch is tracked with `jj branch list --tracked `. - ### Automatic tracking of branches & `git.auto-local-branch` option There are two situations where `jj` tracks branches automatically. `jj git @@ -130,10 +128,10 @@ marked as tracked. By default, every other remote branch is marked as "not tracked" when it's fetched. If desired, you need to manually `jj branch track` them. This works -well for repositories where multiple people work on a large number of branches. +well for repositories where multiple people work on a large number of branches. The default can be changed by setting the config `git.auto-local-branch = true`. -Then, `jj git fetch` tracks every *newly fetched* branch with a local branch. +Then, `jj git fetch` tracks every _newly fetched_ branch with a local branch. Branches that already existed before the `jj git fetch` are not affected. This is similar to Mercurial, which fetches all its bookmarks (equivalent to Git branches) by default. @@ -143,13 +141,13 @@ branches) by default. Currently Jujutsu automatically moves local branches when these conditions are met: - * When a commit has been rewritten (e.g, when you rebase) branches and the - working-copy will move along with it. - * When a commit has been abandoned, all associated branches will be moved - to its parent(s). If a working copy was pointing to the abandoned commit, - then a new working-copy commit will be created on top of the parent(s). +- When a commit has been rewritten (e.g, when you rebase) branches and the + working-copy will move along with it. +- When a commit has been abandoned, all associated branches will be moved + to its parent(s). If a working copy was pointing to the abandoned commit, + then a new working-copy commit will be created on top of the parent(s). -You could describe the movement as following along the change-id of the +You could describe the movement as following along the change-id of the current branch commit, even if it isn't entirely accurate. ## Conflicts diff --git a/docs/cli-reference.md b/docs/cli-reference.md index 5314592b52..b5e835f1fe 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -16,10 +16,8 @@ - {% include-markdown "../cli/tests/cli-reference@.md.snap" rewrite-relative-urls=false start="" %} - diff --git a/docs/code-of-conduct.md b/docs/code-of-conduct.md index ffef778580..c1024c9045 100644 --- a/docs/code-of-conduct.md +++ b/docs/code-of-conduct.md @@ -1,4 +1,3 @@ - # Contributor Covenant Code of Conduct ## Our Pledge @@ -18,23 +17,23 @@ diverse, inclusive, and healthy community. Examples of behavior that contributes to a positive environment for our community include: -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -* Focusing on what is best not just for us as individuals, but for the overall +- Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: -* The use of sexualized language or imagery, and sexual attention or advances of +- The use of sexualized language or imagery, and sexual attention or advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email address, +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities diff --git a/docs/config.md b/docs/config.md index 54f5a6a0f5..5a5d5a76c7 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2,7 +2,6 @@ These are the config settings available to jj/Jujutsu. - ## Config files and TOML `jj` loads several types of config settings: @@ -11,11 +10,11 @@ These are the config settings available to jj/Jujutsu. `cli/src/config/` directory in `jj`'s source repo. - The user settings. These can be edited with `jj config edit --user`. User -settings are located in [the user config file], which can be found with `jj + settings are located in [the user config file], which can be found with `jj config path --user`. - The repo settings. These can be edited with `jj config edit --repo` and are -located in `.jj/repo/config.toml`. + located in `.jj/repo/config.toml`. - Settings [specified in the command-line](#specifying-config-on-the-command-line). @@ -35,6 +34,7 @@ The first thing to remember is that the value of a setting (the part to the right of the `=` sign) should be surrounded in quotes if it's a string. ### Dotted style and headings + In TOML, anything under a heading can be dotted instead. For example, `user.name = "YOUR NAME"` is equivalent to: @@ -66,7 +66,6 @@ then use whichever suits you in your config. If you mix dotted keys and headings That's probably enough TOML to keep you out of trouble but the [syntax guide] is very short if you ever need to check. - ## User settings ```toml @@ -100,15 +99,15 @@ colors.commit_id = "green" The following colors are available: -* black -* red -* green -* yellow -* blue -* magenta -* cyan -* white -* default +- black +- red +- green +- yellow +- blue +- magenta +- cyan +- white +- default All of them but "default" come in a bright version too, e.g. "bright red". The "default" color can be used to override a color defined by a parent style @@ -239,10 +238,11 @@ ui.graph.style = "square" The symbols used to represent commits or operations can be customized via templates. - * `templates.log_node` for commits (with `Option` keywords) - * `templates.op_log_node` for operations (with `Operation` keywords) +- `templates.log_node` for commits (with `Option` keywords) +- `templates.op_log_node` for operations (with `Operation` keywords) For example: + ```toml [templates] log_node = ''' @@ -334,7 +334,7 @@ Can be customized by the `format_short_signature()` template alias. ### Allow "large" revsets by default Certain commands (such as `jj rebase`) can take multiple revset arguments, but -default to requiring each of those revsets to expand to a *single* revision. +default to requiring each of those revsets to expand to a _single_ revision. This restriction can be overridden by prefixing a revset that the user wants to be able to expand to more than one revision with the [`all:` modifier](revsets.md#the-all-modifier). @@ -437,20 +437,25 @@ ui.editor = "nvim" For GUI editors you possibly need to use a `-w` or `--wait`. Some examples: ```toml -ui.editor = "code -w" # VS Code -ui.editor = "bbedit -w" # BBEdit -ui.editor = "subl -n -w" # Sublime Text -ui.editor = "mate -w" # TextMate -ui.editor = ["C:/Program Files/Notepad++/notepad++.exe", - "-multiInst", "-notabbar", "-nosession", "-noPlugin"] # Notepad++ -ui.editor = "idea --temp-project --wait" #IntelliJ +ui.editor = "code -w" # VS Code +ui.editor = "bbedit -w" # BBEdit +ui.editor = "subl -n -w" # Sublime Text +ui.editor = "mate -w" # TextMate +ui.editor = [ + "C:/Program Files/Notepad++/notepad++.exe", + "-multiInst", + "-notabbar", + "-nosession", + "-noPlugin", +] # Notepad++ +ui.editor = "idea --temp-project --wait" #IntelliJ ``` Obviously, you would only set one line, don't copy them all in! ## Editing diffs -The `ui.diff-editor` setting affects the tool used for editing diffs (e.g. `jj +The `ui.diff-editor` setting affects the tool used for editing diffs (e.g. `jj split`, `jj squash -i`). The default is the special value `:builtin`, which launches a built-in TUI tool (known as [scm-diff-editor]) to edit the diff in your terminal. @@ -479,7 +484,12 @@ will be read from the following config keys. ```toml # merge-tools.kdiff3.program = "kdiff3" # Defaults to the name of the tool if not specified merge-tools.kdiff3.edit-args = [ - "--merge", "--cs", "CreateBakFiles=0", "$left", "$right"] + "--merge", + "--cs", + "CreateBakFiles=0", + "$left", + "$right", +] ``` ### Experimental 3-pane diff editing @@ -509,11 +519,11 @@ this is to start SSH as follows (copy-paste the relevant lines): ```shell ssh -L 17376:localhost:17376 \ - -L 17377:localhost:17377 \ - -L 17378:localhost:17378 \ - -L 17379:localhost:17379 \ - -L 17380:localhost:17380 \ - myhost.example.com + -L 17377:localhost:17377 \ + -L 17378:localhost:17378 \ + -L 17379:localhost:17379 \ + -L 17380:localhost:17380 \ + myhost.example.com ``` `diffedit3-ssh` is set up to use these 5 ports by default. Usually, only the @@ -537,7 +547,6 @@ With that configuration, you should be able to simply `ssh myhost`. - Setting either `ui.diff-editor = "meld-3"` or `ui.diff-editor = "diffedit3"` will result in the diff editor showing 3 panes: the diff on the left and right, and an editing pane in the middle. This allow you to see both sides of the @@ -567,7 +576,6 @@ experience, you can follow [instructions from the Wiki] to configure the [DirDiff Vim plugin] and/or the [vimtabdiff Python script]. [instructions from the Wiki]: https://github.com/martinvonz/jj/wiki/Vim#using-vim-as-a-diff-tool - [DirDiff Vim plugin]: https://github.com/will133/vim-dirdiff [vimtabdiff Python script]: https://github.com/balki/vimtabdiff @@ -578,7 +586,7 @@ by `jj resolve`. For example: ```toml # Use merge-tools.meld.merge-args -ui.merge-editor = "meld" # Or "vscode" or "kdiff3" or "vimdiff" +ui.merge-editor = "meld" # Or "vscode" or "kdiff3" or "vimdiff" # Specify merge-args inline ui.merge-editor = ["meld", "$left", "$base", "$right", "-o", "$output"] ``` @@ -600,15 +608,40 @@ to copy it to your config file verbatim, but you are welcome to customize it.) ```toml # merge-tools.kdiff3.program = "kdiff3" # Defaults to the name of the tool if not specified -merge-tools.kdiff3.merge-args = ["$base", "$left", "$right", "-o", "$output", "--auto"] -merge-tools.meld.merge-args = ["$left", "$base", "$right", "-o", "$output", "--auto-merge"] - -merge-tools.vimdiff.merge-args = ["-f", "-d", "$output", "-M", - "$left", "$base", "$right", - "-c", "wincmd J", "-c", "set modifiable", - "-c", "set write"] +merge-tools.kdiff3.merge-args = [ + "$base", + "$left", + "$right", + "-o", + "$output", + "--auto", +] +merge-tools.meld.merge-args = [ + "$left", + "$base", + "$right", + "-o", + "$output", + "--auto-merge", +] + +merge-tools.vimdiff.merge-args = [ + "-f", + "-d", + "$output", + "-M", + "$left", + "$base", + "$right", + "-c", + "wincmd J", + "-c", + "set modifiable", + "-c", + "set write", +] merge-tools.vimdiff.program = "vim" -merge-tools.vimdiff.merge-tool-edits-conflict-markers = true # See below for an explanation +merge-tools.vimdiff.merge-tool-edits-conflict-markers = true # See below for an explanation ``` `jj` makes the following substitutions: @@ -643,7 +676,7 @@ conflict is considered fully resolved when there are no conflict markers left. ## Commit Signing -`jj` can be configured to sign and verify the commits it creates using either +`jj` can be configured to sign and verify the commits it creates using either GnuPG or SSH signing keys. To do this you need to configure a signing backend. @@ -694,8 +727,8 @@ signing.backends.ssh.program = "/path/to/ssh-keygen" When verifying commit signatures the ssh backend needs to be provided with an allowed-signers file containing the public keys of authors whose signatures you want to be able to verify. -You can find the format for this file in the -[ssh-keygen man page](https://man.openbsd.org/ssh-keygen#ALLOWED_SIGNERS). This can be provided +You can find the format for this file in the +[ssh-keygen man page](https://man.openbsd.org/ssh-keygen#ALLOWED_SIGNERS). This can be provided as follows: ```toml @@ -852,7 +885,7 @@ to a TOML file that will be used instead of any configuration file in the default locations. For example, ```shell -env JJ_CONFIG=/dev/null jj log # Ignores any settings specified in the config file. +env JJ_CONFIG=/dev/null jj log # Ignores any settings specified in the config file. ``` ### Specifying config on the command-line diff --git a/docs/conflicts.md b/docs/conflicts.md index 9f22265f14..1561ee5512 100644 --- a/docs/conflicts.md +++ b/docs/conflicts.md @@ -1,6 +1,5 @@ # First-class conflicts - ## Introduction Unlike most other VCSs, Jujutsu can record conflicted states in commits. For @@ -8,23 +7,22 @@ example, if you rebase a commit and it results in a conflict, the conflict will be recorded in the rebased commit and the rebase operation will succeed. You can then resolve the conflict whenever you want. Conflicted states can be further rebased, merged, or backed out. Note that what's stored in the commit is a -logical representation of the conflict, not conflict *markers*; rebasing a +logical representation of the conflict, not conflict _markers_; rebasing a conflict doesn't result in a nested conflict markers (see [technical doc](technical/conflicts.md) for how this works). - ## Advantages The deeper understanding of conflicts has many advantages: -* Removes the need for things like +- Removes the need for things like `git rebase/merge/cherry-pick/etc --continue`. Instead, you get a single workflow for resolving conflicts: check out the conflicted commit, resolve conflicts, and amend. -* Enables the "auto-rebase" feature, where descendants of rewritten commits +- Enables the "auto-rebase" feature, where descendants of rewritten commits automatically get rewritten. This feature mostly replaces Mercurial's [Changeset Evolution](https://www.mercurial-scm.org/wiki/ChangesetEvolution). -* Lets us define the change in a merge commit as being compared to the merged +- Lets us define the change in a merge commit as being compared to the merged parents. That way, we can rebase merge commits correctly (unlike both Git and Mercurial). That includes conflict resolutions done in the merge commit, addressing a common use case for @@ -32,25 +30,24 @@ The deeper understanding of conflicts has many advantages: Since the changes in a merge commit are displayed and rebased as expected, [evil merges](https://git-scm.com/docs/gitglossary/2.22.0#Documentation/gitglossary.txt-aiddefevilmergeaevilmerge) are arguably not as evil anymore. -* Allows you to postpone conflict resolution until you're ready for it. You +- Allows you to postpone conflict resolution until you're ready for it. You can easily keep all your work-in-progress commits rebased onto upstream's head if you like. -* [Criss-cross merges](https://stackoverflow.com/questions/26370185/how-do-criss-cross-merges-arise-in-git) +- [Criss-cross merges](https://stackoverflow.com/questions/26370185/how-do-criss-cross-merges-arise-in-git) and [octopus merges](https://git-scm.com/docs/git-merge#Documentation/git-merge.txt-octopus) become trivial (implementation-wise); some cases that Git can't currently handle, or that would result in nested conflict markers, can be automatically resolved. -* Enables collaborative conflict resolution. (This assumes that you can share +- Enables collaborative conflict resolution. (This assumes that you can share the conflicts with others, which you probably shouldn't do if some people interact with your project using Git.) For information about how conflicts are handled in the working copy, see [here](working-copy.md#conflicts). - ## Conflict markers -Conflicts are "materialized" using *conflict markers* in various contexts. For +Conflicts are "materialized" using _conflict markers_ in various contexts. For example, when you run `jj edit` on a commit with a conflict, it will be materialized in the working copy. Conflicts are also materialized when they are part of diff output (e.g. `jj show` on a commit that introduces or resolves a diff --git a/docs/contributing.md b/docs/contributing.md index f767d35d4a..a5e41659b8 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,6 +1,5 @@ # How to Contribute - ## Policies We'd love to accept your patches and contributions to this project. There are @@ -42,8 +41,8 @@ message. When you address comments on a PR, don't make the changes in a commit on top (as is typical on GitHub). Instead, please make the changes in the appropriate -commit. You can do that by creating a new commit on top of the initial commit - (`jj new `) and then squash in the changes when you're done (`jj squash`). +commit. You can do that by creating a new commit on top of the initial commit +(`jj new `) and then squash in the changes when you're done (`jj squash`). `jj git push` will automatically force-push the branch. @@ -64,7 +63,6 @@ your company's interests, do feel free to approve it. This project follows [Google's Open Source Community Guidelines](https://opensource.google/conduct/). - ## Contributing to the documentation We appreciate [bug @@ -93,7 +91,6 @@ directory](https://github.com/martinvonz/jj/tree/main/cli/src/commands). Working on them requires setting up a Rust development environment, as described below, and may occasionally require adjusting a test. - ## Learning Rust In addition to the [Rust Book](https://doc.rust-lang.org/book/) and the other @@ -154,7 +151,7 @@ These are listed roughly in order of decreasing importance. The `--workspace` flag is needed to run the tests on all crates; by default, only the crate in the current directory is tested. -2. GitHub CI checks require that the code is formatted with the *nightly* +2. GitHub CI checks require that the code is formatted with the _nightly_ version of `rustfmt`. To do this on your computer, install the nightly toolchain and use `cargo +nightly fmt`. @@ -172,7 +169,7 @@ These are listed roughly in order of decreasing importance. 6. To run tests more quickly, use `cargo nextest run --workspace`. To use `nextest` with `insta`, use `cargo insta test --workspace - --test-runner nextest`. +--test-runner nextest`. On Linux, you may be able to speed up `nextest` even further by using the `mold` linker, as explained below. @@ -206,7 +203,6 @@ to use" instructions](https://github.com/rui314/mold#how-to-use). On recent versions of MacOS, the default linker Rust uses is already multi-threaded. It should use all the CPU cores without any configuration. - ## Previewing the HTML documentation The documentation for `jj` is automatically published to the website at @@ -225,7 +221,7 @@ installation instructions]. Finally, follow the [Poetry installation instructions]. [Python installation instructions]: https://docs.python.org/3/using/index.html -[Poetry installation instructions]: https://python-poetry.org/docs/#installation +[Poetry installation instructions]: https://python-poetry.org/docs/#installation Once you have `poetry` installed, you should ask it to install the rest of the required tools into a virtual environment as follows: @@ -282,54 +278,54 @@ The different versions of documentation are managed and deployed with On a POSIX system or WSL, one way to build the entire website is as follows (on Windows, you'll need to understand and adapt the shell script): -1. Check out `jj` as a co-located `jj + git` repository (`jj clone --colocate`), -cloned from your fork of `jj` (e.g. `jjfan.github.com/jj`). You can also use a -pure Git repo if you prefer. +1. Check out `jj` as a co-located `jj + git` repository (`jj clone --colocate`), + cloned from your fork of `jj` (e.g. `jjfan.github.com/jj`). You can also use a + pure Git repo if you prefer. -2. Make sure `jjfan.github.com/jj` includes the `gh-pages` branch of the jj repo -and run `git fetch origin gh-pages`. +2. Make sure `jjfan.github.com/jj` includes the `gh-pages` branch of the jj repo + and run `git fetch origin gh-pages`. -3. Go to the GitHub repository settings, enable GitHub Pages, and configure them -to use the `gh-pages` branch (this is usually the default). +3. Go to the GitHub repository settings, enable GitHub Pages, and configure them + to use the `gh-pages` branch (this is usually the default). -4. Run the same `sh` script that is used in GitHub CI (details below): +4. Run the same `sh` script that is used in GitHub CI (details below): ```shell - .github/scripts/docs-build-deploy 'https://jjfan.github.io/jj/'\ - prerelease main --push + .github/scripts/docs-build-deploy 'https://jjfan.github.io/jj/' \ + prerelease main --push ``` This should build the version of the docs from the current commit, deploy it as a new commit to the `gh-pages` branch, and push the `gh-pages` branch to the origin. -5. Now, you should be able to see the full website, including your latest changes -to the `prerelease` version, at `https://jjfan.github.io/jj/prerelease/`. +5. Now, you should be able to see the full website, including your latest changes + to the `prerelease` version, at `https://jjfan.github.io/jj/prerelease/`. -6. (Optional) The previous steps actually only rebuild -`https://jjfan.github.io/jj/prerelease/` and its alias -`https://jjfan.github.io/jj/main/`. If you'd like to test out version switching -back and forth, you can also rebuild the docs for the latest release as follows. +6. (Optional) The previous steps actually only rebuild + `https://jjfan.github.io/jj/prerelease/` and its alias + `https://jjfan.github.io/jj/main/`. If you'd like to test out version switching + back and forth, you can also rebuild the docs for the latest release as follows. - ```shell - jj new v1.33.1 # Let's say `jj 1.33.1` is the currently the latest release - .github/scripts/docs-build-deploy 'https://jjfan.github.io/jj/'\ - v1.33.1 latest --push - ``` + ```shell + jj new v1.33.1 # Let's say `jj 1.33.1` is the currently the latest release + .github/scripts/docs-build-deploy 'https://jjfan.github.io/jj/'\ + v1.33.1 latest --push + ``` -7. (Optional) When you are done, you may want to reset the `gh-branches` to the -same spot as it is in the upstream. If you configured the `upstream` remote, -this can be done with: +7. (Optional) When you are done, you may want to reset the `gh-branches` to the + same spot as it is in the upstream. If you configured the `upstream` remote, + this can be done with: - ```shell - # This will LOSE any changes you made to `gh-pages` - jj git fetch --remote upstream - jj branch set gh-pages -r gh-pages@upstream - jj git push --remote origin --branch gh-pages - ``` + ```shell + # This will LOSE any changes you made to `gh-pages` + jj git fetch --remote upstream + jj branch set gh-pages -r gh-pages@upstream + jj git push --remote origin --branch gh-pages + ``` - If you want to preserve some of the changes you made, you can do `jj branch - set my-changes -r gh-pages` BEFORE running the above commands. + If you want to preserve some of the changes you made, you can do `jj branch + set my-changes -r gh-pages` BEFORE running the above commands. #### Explanation of the `docs-build-deploy` script @@ -348,43 +344,46 @@ to avoid files that will be overwritten by future invocations of `mike`. Then, you can submit a PR based on the `gh-pages` branch of (instead of the usual `main` branch). - ## Modifying protobuffers (this is not common) - Occasionally, you may need to change the `.proto` files that define jj's data - storage format. In this case, you will need to add a few steps to the above - workflow. +Occasionally, you may need to change the `.proto` files that define jj's data +storage format. In this case, you will need to add a few steps to the above +workflow. - - Install the `protoc` compiler. This usually means either `apt-get install - protobuf-compiler` or downloading [an official release]. The - `prost` [library docs] have additional advice. - - Run `cargo run -p gen-protos` regularly (or after every edit to a `.proto` - file). This is the same as running `cargo run` from `lib/gen-protos`. The - `gen-protos` binary will use the `prost-build` library to compile the - `.proto` files into `.rs` files. - - If you are adding a new `.proto` file, you will need to edit the list of - these files in `lib/gen-protos/src/main.rs`. +- Install the `protoc` compiler. This usually means either `apt-get install +protobuf-compiler` or downloading [an official release]. The + `prost` [library docs] have additional advice. +- Run `cargo run -p gen-protos` regularly (or after every edit to a `.proto` + file). This is the same as running `cargo run` from `lib/gen-protos`. The + `gen-protos` binary will use the `prost-build` library to compile the + `.proto` files into `.rs` files. +- If you are adding a new `.proto` file, you will need to edit the list of + these files in `lib/gen-protos/src/main.rs`. [an official release]: https://github.com/protocolbuffers/protobuf/releases [library docs]: https://docs.rs/prost-build/latest/prost_build/#sourcing-protoc - The `.rs` files generated from `.proto` files are included in the repository, - and there is a GitHub CI check that will complain if they do not match. +The `.rs` files generated from `.proto` files are included in the repository, +and there is a GitHub CI check that will complain if they do not match. ## Profiling One easy-to-use sampling profiler is [samply](https://github.com/mstange/samply). For example: + ```shell cargo install samply samply record jj diff ``` + Then just open the link it prints. Another option is to use the instrumentation we've added manually (using `tracing::instrument`) in various places. For example: + ```shell JJ_TRACE=/tmp/trace.json jj diff ``` + Then go to `https://ui.perfetto.dev/` in Chrome and load `/tmp/trace.json` from there. diff --git a/docs/design/run.md b/docs/design/run.md index 99228b9ec8..05f938d497 100644 --- a/docs/design/run.md +++ b/docs/design/run.md @@ -4,27 +4,27 @@ Authors: [Philip Metzger](mailto:philipmetzger@bluewin.ch), [Martin von Zweigber Initial Version, 10.12.2022 (view full history [here](https://docs.google.com/document/d/14BiAoEEy_e-BRPHYpXRFjvHMfgYVKh-pKWzzTDi-v-g/edit)) - -**Summary:** This Document documents the design of a new `run` command for +**Summary:** This Document documents the design of a new `run` command for Jujutsu which will be used to seamlessly integrate with build systems, linters -and formatters. This is achieved by running a user-provided command or script -across multiple revisions. For more details, read the +and formatters. This is achieved by running a user-provided command or script +across multiple revisions. For more details, read the [Use-Cases of jj run](#use-cases-of-jj-run). ## Preface The goal of this Design Document is to specify the correct behavior of `jj run`. -The points we decide on here I (Philip Metzger) will try to implement. There +The points we decide on here I (Philip Metzger) will try to implement. There exists some prior work in other DVCS: -* `git test`: part of [git-branchless]. Similar to this proposal for `jj run`. -* `hg run`: Google's internal Mercurial extension. Similar to this proposal for -`jj run`. -Details not available. -* `hg fix`: Google's open source Mercurial extension: [source code][fix-src]. A -more specialized approach to rewriting file content without full context of the -working directory. -* `git rebase -x`: runs commands opportunistically as part of rebase. -* `git bisect run`: run a command to determine which commit introduced a bug. + +- `git test`: part of [git-branchless]. Similar to this proposal for `jj run`. +- `hg run`: Google's internal Mercurial extension. Similar to this proposal for + `jj run`. + Details not available. +- `hg fix`: Google's open source Mercurial extension: [source code][fix-src]. A + more specialized approach to rewriting file content without full context of the + working directory. +- `git rebase -x`: runs commands opportunistically as part of rebase. +- `git bisect run`: run a command to determine which commit introduced a bug. ## Context and Scope @@ -32,43 +32,43 @@ The initial need for some kind of command runner integrated in the VCS, surfaced in a [github discussion][pre-commit]. In a [discussion on discord][hooks] about the git-hook model, there was consensus about not repeating their mistakes. -For `jj run` there is prior art in Mercurial, git branchless and Google's +For `jj run` there is prior art in Mercurial, git branchless and Google's internal Mercurial. Currently git-branchless `git test` and `hg fix` implement -some kind of command runner. The Google internal `hg run` works in +some kind of command runner. The Google internal `hg run` works in conjunction with CitC (Clients in the Cloud) which allows it to lazily apply the current command to any affected file. Currently no Jujutsu backend -(Git, Native) has a fancy virtual filesystem supporting it, so we -can't apply this optimization. We could do the same once we have an -implementation of the working copy based on a virtual file system. Until then, -we have to run the commands in regular local-disk working copies. +(Git, Native) has a fancy virtual filesystem supporting it, so we +can't apply this optimization. We could do the same once we have an +implementation of the working copy based on a virtual file system. Until then, +we have to run the commands in regular local-disk working copies. ## Goals and Non-Goals ### Goals -* We should be able to apply the command to any revision, published or unpublished. -* We should be able to parallelize running the actual command, while preserving a -good console output. -* The run command should be able to work in any commit, the working-copy commit -itself or any other commit. -* There should exist some way to signal hard failure. -* The command should build enough infrastructure for `jj test`, `jj fix` and -`jj format`. -* The main goal is to be good enough, as we can always expand the functionality -in the future. +- We should be able to apply the command to any revision, published or unpublished. +- We should be able to parallelize running the actual command, while preserving a + good console output. +- The run command should be able to work in any commit, the working-copy commit + itself or any other commit. +- There should exist some way to signal hard failure. +- The command should build enough infrastructure for `jj test`, `jj fix` and + `jj format`. +- The main goal is to be good enough, as we can always expand the functionality + in the future. ### Non-Goals -* While we should build a base for `jj test`, `jj format` and `jj fix`, we -shouldn't mash their use-cases into `jj run`. -* The command shouldn't be too smart, as too many assumptions about workflows -makes the command confusing for users. -* The smart caching of outputs, as user input commands can be unpredictable. -makes the command confusing for users. -* Avoid the smart caching of outputs, as user input commands can be -unpredictable. -* Fine grained user facing configuration, as it's unwarranted complexity. -* A `fix` subcommand as it cuts too much design space. +- While we should build a base for `jj test`, `jj format` and `jj fix`, we + shouldn't mash their use-cases into `jj run`. +- The command shouldn't be too smart, as too many assumptions about workflows + makes the command confusing for users. +- The smart caching of outputs, as user input commands can be unpredictable. + makes the command confusing for users. +- Avoid the smart caching of outputs, as user input commands can be + unpredictable. +- Fine grained user facing configuration, as it's unwarranted complexity. +- A `fix` subcommand as it cuts too much design space. ## Use-Cases of jj run @@ -88,89 +88,89 @@ unpredictable. - `jj run 'bazel build //some/target:somewhere'` - `jj run 'ninja check-lld'` -Some of these use-cases should get a specialized command, as this allows -further optimization. A command could be `jj format`, which runs a list of -formatters over a subset of a file in a revision. Another command could be +Some of these use-cases should get a specialized command, as this allows +further optimization. A command could be `jj format`, which runs a list of +formatters over a subset of a file in a revision. Another command could be `jj fix`, which runs a command like `rustfmt --fix` or `cargo clippy --fix` over a subset of a file in a revision. ## Design -### Base Design +### Base Design -All the work will be done in the `.jj/` directory. This allows us to hide all +All the work will be done in the `.jj/` directory. This allows us to hide all complexity from the users, while preserving the user's current workspace. -We will copy the approach from git-branchless's `git test` of creating a -temporary working copy for each parallel command. The working copies will be -reused between `jj run` invocations. They will also be reused within `jj run` +We will copy the approach from git-branchless's `git test` of creating a +temporary working copy for each parallel command. The working copies will be +reused between `jj run` invocations. They will also be reused within `jj run` invocation if there are more commits to run on than there are parallel jobs. -We will leave ignored files in the temporary directory between runs. That +We will leave ignored files in the temporary directory between runs. That enables incremental builds (e.g by letting cargo reuse its `target/` directory). -However, it also means that runs potentially become less reproducible. We will +However, it also means that runs potentially become less reproducible. We will provide a flag for removing ignored files from the temporary working copies to -address that. +address that. Another problem with leaving ignored files in the temporary directories is that -they take up space. That is especially problematic in the case of cargo (the +they take up space. That is especially problematic in the case of cargo (the `target/` directory often takes up tens of GBs). The same flag for cleaning up -ignored files can be used to address that. We may want to also have a flag for -cleaning up temporary working copies *after* running the command. +ignored files can be used to address that. We may want to also have a flag for +cleaning up temporary working copies _after_ running the command. -An early version of the command will directly use [Treestate] to -to manage the temporary working copies. That means that running `jj` inside the +An early version of the command will directly use [Treestate] to +to manage the temporary working copies. That means that running `jj` inside the temporary working copies will not work . We can later extend that to use a full -[Workspace]. To prevent operations in the working copies from +[Workspace]. To prevent operations in the working copies from impacting the repo, we can use a separate [OpHeadsStore] for it. ### Modifying the Working Copy -Since the subprocesses will run in temporary working copies, they +Since the subprocesses will run in temporary working copies, they won't interfere with the user's working copy. The user can therefore continue -to work in it while `jj run` is running. +to work in it while `jj run` is running. We want subprocesses to be able to make changes to the repo by updating their -assigned working copy. Let's say the user runs `jj run` on just commits A and -B, where B's parent is A. Any changes made on top of A would be squashed into +assigned working copy. Let's say the user runs `jj run` on just commits A and +B, where B's parent is A. Any changes made on top of A would be squashed into A, forming A'. Similarly B' would be formed by squasing it into B. We can then either do a normal rebase of B' onto A', or we can simply update its parent to A'. The former is useful, e.g when the subprocess only makes a partial update -of the tree based on the parent commit. In addition to these two modes, we may -want to have an option to ignore any changes made in the subprocess's working +of the tree based on the parent commit. In addition to these two modes, we may +want to have an option to ignore any changes made in the subprocess's working copy. ### Modifying the Repo -Once we give the subprocess access to a fork of the repo via separate +Once we give the subprocess access to a fork of the repo via separate [OpHeadsStore], it will be able to create new operations in its fork. If the user runs `jj run -r foo` and the subprocess checks out another commit, -it's not clear what that should do. We should probably just verify that the +it's not clear what that should do. We should probably just verify that the working-copy commit's parents are unchanged after the subprocess returns. Any -operations created by the subprocess will be ignored. +operations created by the subprocess will be ignored. -### Rewriting the revisions +### Rewriting the revisions Like all commands, `jj run` will refuse to rewrite public/immutable commits. -For private/unpublished revisions, we either amend or reparent the changes, +For private/unpublished revisions, we either amend or reparent the changes, which are available as command options. ## Execution order/parallelism -It may be useful to execute commands in topological order. For example, -commands with costs proportional to incremental changes, like build systems. +It may be useful to execute commands in topological order. For example, +commands with costs proportional to incremental changes, like build systems. There may also be other relevant heuristics, but topological order is an easy -and effective way to start. +and effective way to start. -Parallel execution of commands on different commits may choose to schedule +Parallel execution of commands on different commits may choose to schedule commits to still reduce incremental changes in the working copy used by each -execution slot/"thread". However, running the command on all commits -concurrently should be possible if desired. +execution slot/"thread". However, running the command on all commits +concurrently should be possible if desired. -Executing commands in topological order allows for more meaningful use of any -potential features that stop execution "at the first failure". For example, -when running tests on a chain of commits, it might be useful to proceed in -topological/chronological order, and stop on the first failure, because it +Executing commands in topological order allows for more meaningful use of any +potential features that stop execution "at the first failure". For example, +when running tests on a chain of commits, it might be useful to proceed in +topological/chronological order, and stop on the first failure, because it might imply that the remaining executions will be undesirable because they will also fail. @@ -178,69 +178,69 @@ also fail. It will be useful to have multiple strategies to deal with failures on a single or multiple revisions. The reason for these strategies is to allow customized -conflict handling. These strategies then can be exposed in the ui with a +conflict handling. These strategies then can be exposed in the ui with a matching option. -**Continue:** If any subprocess fails, we will continue the work on child -revisions. Notify the user on exit about the failed revisions. +**Continue:** If any subprocess fails, we will continue the work on child +revisions. Notify the user on exit about the failed revisions. **Stop:** Signal a fatal failure and cancel any scheduled work that has not yet started running, but let any already started subprocess finish. Notify the -user about the failed command and display the generated error from the -subprocess. +user about the failed command and display the generated error from the +subprocess. -**Fatal:** Signal a fatal failure and immediately stop processing and kill any -running processes. Notify the user that we failed to apply the command to the -specific revision. +**Fatal:** Signal a fatal failure and immediately stop processing and kill any +running processes. Notify the user that we failed to apply the command to the +specific revision. We will leave any affected commit in its current state, if any subprocess fails. -This allows us to provide a better user experience, as leaving revisions in an +This allows us to provide a better user experience, as leaving revisions in an undesirable state, e.g partially formatted, may confuse users. ## Resource constraints -It will be useful to constrain the execution to prevent resource exhaustion. +It will be useful to constrain the execution to prevent resource exhaustion. Relevant resources could include: -- CPU and memory available on the machine running the commands. `jj run` can -provide some simple mitigations like limiting parallelism to "number of CPUs" -by default, and limiting parallelism by dividing "available memory" by some -estimate or measurement of per-invocation memory use of the commands. -- External resources that are not immediately known to jj. For example, -commands run in parallel may wish to limit the total number of connections -to a server. We might choose to defer any handling of this to the -implementation of the command being invoked, instead of trying to -communicate that information to jj. +- CPU and memory available on the machine running the commands. `jj run` can + provide some simple mitigations like limiting parallelism to "number of CPUs" + by default, and limiting parallelism by dividing "available memory" by some + estimate or measurement of per-invocation memory use of the commands. +- External resources that are not immediately known to jj. For example, + commands run in parallel may wish to limit the total number of connections + to a server. We might choose to defer any handling of this to the + implementation of the command being invoked, instead of trying to + communicate that information to jj. ## Command Options -The base command of any jj command should be usable. By default `jj run` works +The base command of any jj command should be usable. By default `jj run` works on the `@` the current working copy. -* --command, explicit name of the first argument -* -x, for git compatibility (may alias another command) -* -j, --jobs, the amount of parallelism to use -* -k, --keep-going, continue on failure (may alias another command) -* --show, display the diff for an affected revision -* --dry-run, do the command execution without doing any work, logging all -intended files and arguments -* --rebase, rebase all parents on the consulitng diff (may alias another -command) -* --reparent, change the parent of an effected revision to the new change -(may alias another command) -* --clean, remove existing workspaces and remove the ignored files -* --readonly, ignore changes across multiple run invocations -* --error-strategy=`continue|stop|fatal`, see [Dealing with failure](#dealing-with-failure) + +- --command, explicit name of the first argument +- -x, for git compatibility (may alias another command) +- -j, --jobs, the amount of parallelism to use +- -k, --keep-going, continue on failure (may alias another command) +- --show, display the diff for an affected revision +- --dry-run, do the command execution without doing any work, logging all + intended files and arguments +- --rebase, rebase all parents on the consulitng diff (may alias another + command) +- --reparent, change the parent of an effected revision to the new change + (may alias another command) +- --clean, remove existing workspaces and remove the ignored files +- --readonly, ignore changes across multiple run invocations +- --error-strategy=`continue|stop|fatal`, see [Dealing with failure](#dealing-with-failure) ### Integrating with other commands `jj log`: No special handling needed `jj diff`: No special handling needed `jj st`: For now reprint the final output of `jj run` -`jj op log`: No special handling needed, but awaits further discussion in +`jj op log`: No special handling needed, but awaits further discussion in [#963][issue] `jj undo/jj op undo`: No special handling needed - ## Open Points Should the command be working copy backend specific? @@ -249,21 +249,19 @@ Configuration options, User and Repository Wide? ## Future possibilities -- We could rewrite the file in memory, which is a neat optimization -- Exposing some internal state, to allow preciser resource constraints -- Integration options for virtual filesystems, which allow them to cache the -needed working copies. +- We could rewrite the file in memory, which is a neat optimization +- Exposing some internal state, to allow preciser resource constraints +- Integration options for virtual filesystems, which allow them to cache the + needed working copies. - A Jujutsu wide concept for a cached working copy, as they could be expensive -to materialize. -- Customized failure messages, this maybe useful for bots, it could be similar -to Bazel's `select(..., message = "arch not supported for $project")`. + to materialize. +- Customized failure messages, this maybe useful for bots, it could be similar + to Bazel's `select(..., message = "arch not supported for $project")`. - Make `jj run` asynchronous by spawning a `main` process, directly return to the -user and incrementally updating the output of `jj st`. - - + user and incrementally updating the output of `jj st`. [git-branchless]: https://github.com/arxanas/git-branchless -[issue]: https://github.com/martinvonz/jj/issues/963 +[issue]: https://github.com/martinvonz/jj/issues/963 [fix-src]: https://repo.mercurial-scm.org/hg/file/tip/hgext/fix.py [hooks]: https://discord.com/channels/968932220549103686/969829516539228222/1047958933161119795 [OpHeadsStore]: https://github.com/martinvonz/jj/blob/main/lib/src/op_heads_store.rs diff --git a/docs/design/sparse-v2.md b/docs/design/sparse-v2.md index 4bf4f2b3c9..31cf62475e 100644 --- a/docs/design/sparse-v2.md +++ b/docs/design/sparse-v2.md @@ -290,8 +290,8 @@ missing working copy infos with a default `WorkingCopyPatterns` as needed. #### Related Work [Perforce client maps](https://www.perforce.com/manuals/cmdref/Content/CmdRef/views.html) - are very similar in concept to the entirety of `WorkingCopyPatterns`, and this - design aims to achieve similar functionality. +are very similar in concept to the entirety of `WorkingCopyPatterns`, and this +design aims to achieve similar functionality. The [Josh Project](https://github.com/josh-project/josh) implements partial git clones in a way similar to how sparse patterns try to work. diff --git a/docs/design/tracking-branches.md b/docs/design/tracking-branches.md index 68aaf21df9..eefdf37a33 100644 --- a/docs/design/tracking-branches.md +++ b/docs/design/tracking-branches.md @@ -10,8 +10,9 @@ with a number of branches. The `git.auto-local-branch` config can mitigate this problem, but we'll get locally-deleted branches instead. The goal of this plan is to implement -* proper support for tracking/non-tracking remote branches -* logically consistent data model for importing/exporting Git refs + +- proper support for tracking/non-tracking remote branches +- logically consistent data model for importing/exporting Git refs [#1136]: https://github.com/martinvonz/jj/issues/1136 @@ -35,12 +36,12 @@ git_refs git_head: target? ``` -* Remote branches are stored in both `branches[name].remote_targets` and +- Remote branches are stored in both `branches[name].remote_targets` and `git_refs["refs/remotes"]`. These two are mostly kept in sync, but there are two scenarios where remote-tracking branches and git refs can diverge: 1. `jj branch forget` 2. `jj op undo`/`restore` in colocated repo -* Pseudo `@git` tracking branches are stored in `git_refs["refs/heads"]`. We +- Pseudo `@git` tracking branches are stored in `git_refs["refs/heads"]`. We need special case to resolve `@git` branches, and their behavior is slightly different from the other remote-tracking branches. @@ -84,8 +85,9 @@ git_refs # last imported/exported refs ``` With the proposed data model, we can -* naturally support remote branches which have no local counterparts -* deduplicate `branches[name].remote_targets` and `git_refs["refs/remotes"]` + +- naturally support remote branches which have no local counterparts +- deduplicate `branches[name].remote_targets` and `git_refs["refs/remotes"]` ### Import/export data flow @@ -112,11 +114,11 @@ With the proposed data model, we can +---------------+ --' ``` -* `jj git import` applies diff between `git_refs` and `remotes[]`. `git_refs` is +- `jj git import` applies diff between `git_refs` and `remotes[]`. `git_refs` is always copied from the backing Git repo. -* `jj git export` copies jj's `remotes` view back to the Git repo. If a ref in +- `jj git export` copies jj's `remotes` view back to the Git repo. If a ref in the Git repo has been updated since the last import, the ref isn't exported. -* `jj op restore` never rolls back `git_refs`. +- `jj op restore` never rolls back `git_refs`. ### Tracking state @@ -148,13 +150,13 @@ fn target_in_merge_context(known_target, state) { ### Mapping to the current data model -* New `remotes["git"].branches` corresponds to `git_refs["refs/heads"]`, but +- New `remotes["git"].branches` corresponds to `git_refs["refs/heads"]`, but forgotten branches are removed from `remotes["git"].branches`. -* New `remotes["git"].tags` corresponds to `git_refs["refs/tags"]`. -* New `remotes["git"].head` corresponds to `git_head`. -* New `remotes[remote].branches` corresponds to +- New `remotes["git"].tags` corresponds to `git_refs["refs/tags"]`. +- New `remotes["git"].head` corresponds to `git_head`. +- New `remotes[remote].branches` corresponds to `branches[].remote_targets[remote]`. -* `state = new|tracking` doesn't exist in the current model. It's determined +- `state = new|tracking` doesn't exist in the current model. It's determined by `git.auto-local-branch` config. ## Common command behaviors @@ -165,47 +167,50 @@ In particular, a merge of local and remote targets is ### fetch/import -* `jj git fetch` +- `jj git fetch` + 1. Fetches remote changes to the backing Git repo. 2. Import changes only for `remotes[remote].branches[glob]` (see below) - * TODO: how about fetched `.tags`? + - TODO: how about fetched `.tags`? -* `jj git import` +- `jj git import` 1. Copies `git_refs` from the backing Git repo. 2. Calculates diff from the known `remotes` to the new `git_refs`. - * `git_refs["refs/heads"] - remotes["git"].branches` - * `git_refs["refs/tags"] - remotes["git"].tags` - * TBD: `"HEAD" - remotes["git"].head` (unused) - * `git_refs["refs/remotes/{remote}"] - remotes[remote]` + - `git_refs["refs/heads"] - remotes["git"].branches` + - `git_refs["refs/tags"] - remotes["git"].tags` + - TBD: `"HEAD" - remotes["git"].head` (unused) + - `git_refs["refs/remotes/{remote}"] - remotes[remote]` 3. Merges diff in local `branches` and `tags` if `state` is `tracking`. - * If the known `target` is `absent`, the default `state` should be + - If the known `target` is `absent`, the default `state` should be calculated. This also applies to previously-forgotten branches. 4. Updates `remotes` reflecting the import. 5. Abandons commits that are no longer referenced. ### push/export -* `jj git push` +- `jj git push` + 1. Calculates diff from the known `remotes[remote]` to the local changes. - * `branches - remotes[remote].branches` - * If `state` is `new` (i.e. untracked), the known remote branch `target` + - `branches - remotes[remote].branches` + - If `state` is `new` (i.e. untracked), the known remote branch `target` is considered `absent`. - * If `state` is `new`, and if the local branch `target` is `absent`, the + - If `state` is `new`, and if the local branch `target` is `absent`, the diff `[absent, remote] - absent` is noop. So it's not allowed to push deleted branch to untracked remote. - * TODO: Copy Git's `--force-with-lease` behavior? - * ~`tags`~ (not implemented, but should be the same as `branches`) + - TODO: Copy Git's `--force-with-lease` behavior? + - ~`tags`~ (not implemented, but should be the same as `branches`) 2. Pushes diff to the remote Git repo (as well as remote tracking branches in the backing Git repo.) 3. Updates `remotes[remote]` and `git_refs` reflecting the push. -* `jj git export` +- `jj git export` + 1. Copies local `branches`/`tags` back to `remotes["git"]`. - * Conceptually, `remotes["git"].branches[name].state` can be set to + - Conceptually, `remotes["git"].branches[name].state` can be set to untracked. Untracked local branches won't be exported to Git. - * If `remotes["git"].branches[name]` is `absent`, the default + - If `remotes["git"].branches[name]` is `absent`, the default `state = tracking` applies. This also applies to forgotten branches. - * ~`tags`~ (not implemented, but should be the same as `branches`) + - ~`tags`~ (not implemented, but should be the same as `branches`) 2. Calculates diff from the known `git_refs` to the new `remotes[remote]`. 3. Applies diff to the backing Git repo. 4. Updates `git_refs` reflecting the export. @@ -215,158 +220,160 @@ In particular, a merge of local and remote targets is ### init/clone -* `jj init` - * Import, track, and merge per `git.auto_local_branch` config. - * If `!git.auto_local_branch`, no `tracking` state will be set. +- `jj init` + + - Import, track, and merge per `git.auto_local_branch` config. + - If `!git.auto_local_branch`, no `tracking` state will be set. -* `jj git clone` - * Import, track, and merge per `git.auto_local_branch` config. - * The default branch will be tracked regardless of `git.auto_local_branch` +- `jj git clone` + - Import, track, and merge per `git.auto_local_branch` config. + - The default branch will be tracked regardless of `git.auto_local_branch` config. This isn't technically needed, but will help users coming from Git. ### branch -* `jj branch set {name}` +- `jj branch set {name}` 1. Sets local `branches[name]` entry. -* `jj branch delete {name}` +- `jj branch delete {name}` 1. Removes local `branches[name]` entry. -* `jj branch forget {name}` +- `jj branch forget {name}` 1. Removes local `branches[name]` entry if exists. 2. Removes `remotes[remote].branches[name]` entries if exist. TODO: maybe better to not remove non-tracking remote branches? -* `jj branch track {name}@{remote}` (new command) +- `jj branch track {name}@{remote}` (new command) 1. Merges `[local, remote] - [absent]` in local branch. - * Same as "fetching/importing existing branch from untracked remote". + - Same as "fetching/importing existing branch from untracked remote". 2. Sets `remotes[remote].branches[name].state = tracking`. -* `jj branch untrack {name}@{remote}` (new command) +- `jj branch untrack {name}@{remote}` (new command) 1. Sets `remotes[remote].branches[name].state = new`. -* `jj branch list` - * TODO: hide non-tracking branches by default? ... +- `jj branch list` + - TODO: hide non-tracking branches by default? ... Note: desired behavior of `jj branch forget` is to -* discard both local and remote branches (without actually removing branches + +- discard both local and remote branches (without actually removing branches at remotes) -* not abandon commits which belongs to those branches (even if the branch is +- not abandon commits which belongs to those branches (even if the branch is removed at a remote) ## Command behavior examples ### fetch/import -* Fetching/importing new branch +- Fetching/importing new branch 1. Decides new `state = new|tracking` based on `git.auto_local_branch` 2. If new `state` is `tracking`, merges `[absent, new_remote] - [absent]` (i.e. creates local branch with `new_remote` target) 3. Sets `remotes[remote].branches[name].state` -* Fetching/importing existing branch from tracking remote +- Fetching/importing existing branch from tracking remote 1. Merges `[local, new_remote] - [known_remote]` -* Fetching/importing existing branch from untracked remote +- Fetching/importing existing branch from untracked remote 1. Decides new `state = new|tracking` based on `git.auto_local_branch` 2. If new `state` is `tracking`, merges `[local, new_remote] - [absent]` 3. Sets `remotes[remote].branches[name].state` -* Fetching/importing remotely-deleted branch from tracking remote +- Fetching/importing remotely-deleted branch from tracking remote 1. Merges `[local, absent] - [known_remote]` 2. Removes `remotes[remote].branches[name]` (`target` becomes `absent`) (i.e. the remote branch is no longer tracked) 3. Abandons commits in the deleted branch -* Fetching/importing remotely-deleted branch from untracked remote +- Fetching/importing remotely-deleted branch from untracked remote 1. Decides new `state = new|tracking` based on `git.auto_local_branch` 2. Noop anyway since `[local, absent] - [absent]` -> `local` -* Fetching previously-forgotten branch from remote +- Fetching previously-forgotten branch from remote 1. Decides new `state = new|tracking` based on `git.auto_local_branch` 2. If new `state` is `tracking`, merges - `[absent, new_remote] - [absent]` -> `new_remote` + `[absent, new_remote] - [absent]` -> `new_remote` 3. Sets `remotes[remote].branches[name].state` -* Fetching forgotten and remotely-deleted branch - * Same as "remotely-deleted branch from untracked remote" since forgotten +- Fetching forgotten and remotely-deleted branch + - Same as "remotely-deleted branch from untracked remote" since forgotten remote branch should be `state = new` - * Therefore, no local commits should be abandoned + - Therefore, no local commits should be abandoned ### push -* Pushing new branch, remote doesn't exist +- Pushing new branch, remote doesn't exist 1. Pushes `[local, absent] - [absent]` -> `local` 2. Sets `remotes[remote].branches[name].target = local`, `.state = tracking` -* Pushing new branch, untracked remote exists +- Pushing new branch, untracked remote exists 1. Pushes `[local, remote] - [absent]` - * Fails if `local` moved backwards or sideways + - Fails if `local` moved backwards or sideways 2. Sets `remotes[remote].branches[name].target = local`, `.state = tracking` -* Pushing existing branch to tracking remote +- Pushing existing branch to tracking remote 1. Pushes `[local, remote] - [remote]` -> `local` - * Fails if `local` moved backwards or sideways, and if `remote` is out of + - Fails if `local` moved backwards or sideways, and if `remote` is out of sync 2. Sets `remotes[remote].branches[name].target = local` -* Pushing existing branch to untracked remote - * Same as "new branch" -* Pushing deleted branch to tracking remote +- Pushing existing branch to untracked remote + - Same as "new branch" +- Pushing deleted branch to tracking remote 1. Pushes `[absent, remote] - [remote]` -> `absent` - * TODO: Fails if `remote` is out of sync? + - TODO: Fails if `remote` is out of sync? 2. Removes `remotes[remote].branches[name]` (`target` becomes `absent`) -* Pushing deleted branch to untracked remote - * Noop since `[absent, remote] - [absent]` -> `remote` - * Perhaps, UI will report error -* Pushing forgotten branch to untracked remote - * Same as "deleted branch to untracked remote" -* Pushing previously-forgotten branch to remote - * Same as "new branch, untracked remote exists" - * The `target` of forgotten remote branch is `absent` +- Pushing deleted branch to untracked remote + - Noop since `[absent, remote] - [absent]` -> `remote` + - Perhaps, UI will report error +- Pushing forgotten branch to untracked remote + - Same as "deleted branch to untracked remote" +- Pushing previously-forgotten branch to remote + - Same as "new branch, untracked remote exists" + - The `target` of forgotten remote branch is `absent` ### export -* Exporting new local branch, git branch doesn't exist +- Exporting new local branch, git branch doesn't exist 1. Sets `remotes["git"].branches[name].target = local`, `.state = tracking` 2. Exports `[local, absent] - [absent]` -> `local` -* Exporting new local branch, git branch is out of sync +- Exporting new local branch, git branch is out of sync 1. Exports `[local, git] - [absent]` -> fail -* Exporting existing local branch, git branch is synced +- Exporting existing local branch, git branch is synced 1. Sets `remotes["git"].branches[name].target = local` 2. Exports `[local, git] - [git]` -> `local` -* Exporting deleted local branch, git branch is synced +- Exporting deleted local branch, git branch is synced 1. Removes `remotes["git"].branches[name]` 2. Exports `[absent, git] - [git]` -> `absent` -* Exporting forgotten branches, git branches are synced +- Exporting forgotten branches, git branches are synced 1. Exports `[absent, git] - [git]` -> `absent` for forgotten local/remote branches ### undo fetch -* Exporting undone fetch, git branches are synced +- Exporting undone fetch, git branches are synced 1. Exports `[old, git] - [git]` -> `old` for undone local/remote branches -* Redoing undone fetch without exporting - * Same as plain fetch since the known `git_refs` isn't diffed against the +- Redoing undone fetch without exporting + - Same as plain fetch since the known `git_refs` isn't diffed against the refs in the backing Git repo. ### `@git` remote -* `jj branch untrack {name}@git` - * Maybe rejected (to avoid confusion)? - * Allowing this would mean different local branches of the same name coexist +- `jj branch untrack {name}@git` + - Maybe rejected (to avoid confusion)? + - Allowing this would mean different local branches of the same name coexist in jj and git. -* `jj git fetch --remote git` - * Rejected. The implementation is different. - * Conceptually, it's `git::import_refs()` only for local branches. -* `jj git push --remote git` - * Rejected. The implementation is different. - * Conceptually, it's `jj branch track` and `git::export_refs()` only for +- `jj git fetch --remote git` + - Rejected. The implementation is different. + - Conceptually, it's `git::import_refs()` only for local branches. +- `jj git push --remote git` + - Rejected. The implementation is different. + - Conceptually, it's `jj branch track` and `git::export_refs()` only for local branches. ## Remaining issues -* https://github.com/martinvonz/jj/issues/1278 pushing to tracked remote - * Option could be added to push to all `tracking` remotes? -* Track remote branch locally with different name - * Local branch name could be stored per remote branch - * Consider UI complexity -* "private" state (suggested by @ilyagr) - * "private" branches can be pushed to their own remote, but not to the +- https://github.com/martinvonz/jj/issues/1278 pushing to tracked remote + - Option could be added to push to all `tracking` remotes? +- Track remote branch locally with different name + - Local branch name could be stored per remote branch + - Consider UI complexity +- "private" state (suggested by @ilyagr) + - "private" branches can be pushed to their own remote, but not to the upstream repo - * This might be a state attached to a local branch (similar to Mercurial's + - This might be a state attached to a local branch (similar to Mercurial's "secret" phase) ## References -* https://github.com/martinvonz/jj/issues/1136 -* https://github.com/martinvonz/jj/issues/1666 -* https://github.com/martinvonz/jj/issues/1690 -* https://github.com/martinvonz/jj/issues/1734 -* https://github.com/martinvonz/jj/pull/1739 +- https://github.com/martinvonz/jj/issues/1136 +- https://github.com/martinvonz/jj/issues/1666 +- https://github.com/martinvonz/jj/issues/1690 +- https://github.com/martinvonz/jj/issues/1734 +- https://github.com/martinvonz/jj/pull/1739 diff --git a/docs/filesets.md b/docs/filesets.md index 18c2d96673..c610494f7a 100644 --- a/docs/filesets.md +++ b/docs/filesets.md @@ -17,9 +17,9 @@ names passed to these commands [must be quoted][string-literals] if they contain whitespace or meta characters. However, as a special case, quotes can be omitted if the expression has no operators nor function calls. For example: -* `jj diff 'Foo Bar'` (shell quotes are required, but inner quotes are optional) -* `jj diff '~"Foo Bar"'` (both shell and inner quotes are required) -* `jj diff '"Foo(1)"'` (both shell and inner quotes are required) +- `jj diff 'Foo Bar'` (shell quotes are required, but inner quotes are optional) +- `jj diff '~"Foo Bar"'` (both shell and inner quotes are required) +- `jj diff '"Foo(1)"'` (both shell and inner quotes are required) [string-literals]: templates.md#string-literals @@ -27,16 +27,16 @@ if the expression has no operators nor function calls. For example: The following patterns are supported: -* `"path"`, `path` (the quotes are optional), or `cwd:"path"`: Matches +- `"path"`, `path` (the quotes are optional), or `cwd:"path"`: Matches cwd-relative path prefix (file or files under directory recursively.) -* `cwd-file:"path"` or `file:"path"`: Matches cwd-relative file (or exact) path. -* `cwd-glob:"pattern"` or `glob:"pattern"`: Matches file paths with cwd-relative +- `cwd-file:"path"` or `file:"path"`: Matches cwd-relative file (or exact) path. +- `cwd-glob:"pattern"` or `glob:"pattern"`: Matches file paths with cwd-relative Unix-style shell [wildcard `pattern`][glob]. For example, `glob:"*.c"` will match all `.c` files in the current working directory non-recursively. -* `root:"path"`: Matches workspace-relative path prefix (file or files under +- `root:"path"`: Matches workspace-relative path prefix (file or files under directory recursively.) -* `root-file:"path"`: Matches workspace-relative file (or exact) path. -* `root-glob:"pattern"`: Matches file paths with workspace-relative Unix-style +- `root-file:"path"`: Matches workspace-relative file (or exact) path. +- `root-glob:"pattern"`: Matches file paths with workspace-relative Unix-style shell [wildcard `pattern`][glob]. [glob]: https://docs.rs/glob/latest/glob/struct.Pattern.html @@ -46,10 +46,10 @@ The following patterns are supported: The following operators are supported. `x` and `y` below can be any fileset expressions. -* `x & y`: Matches both `x` and `y`. -* `x | y`: Matches either `x` or `y` (or both). -* `x ~ y`: Matches `x` but not `y`. -* `~x`: Matches everything but `x`. +- `x & y`: Matches both `x` and `y`. +- `x | y`: Matches either `x` or `y` (or both). +- `x ~ y`: Matches `x` but not `y`. +- `~x`: Matches everything but `x`. You can use parentheses to control evaluation order, such as `(x & y) | z` or `x & (y | z)`. @@ -58,8 +58,8 @@ You can use parentheses to control evaluation order, such as `(x & y) | z` or You can also specify patterns by using functions. -* `all()`: Matches everything. -* `none()`: Matches nothing. +- `all()`: Matches everything. +- `none()`: Matches nothing. ## Examples diff --git a/docs/git-comparison.md b/docs/git-comparison.md index dbda867610..26d2edd14f 100644 --- a/docs/git-comparison.md +++ b/docs/git-comparison.md @@ -6,7 +6,6 @@ This document attempts to describe how Jujutsu is different from Git. See [the Git-compatibility doc](git-compatibility.md) for information about how the `jj` command interoperates with Git repos. - ## Overview Here is a list of conceptual differences between Jujutsu and Git, along with @@ -14,53 +13,52 @@ links to more details where applicable and available. There's a [table further down](#command-equivalence-table) explaining how to achieve various use cases. -* **The working copy is automatically committed.** That results in a simpler and +- **The working copy is automatically committed.** That results in a simpler and more consistent CLI because the working copy is now treated like any other commit. [Details](working-copy.md). -* **There's no index (staging area).** Because the working copy is automatically +- **There's no index (staging area).** Because the working copy is automatically committed, an index-like concept doesn't make sense. The index is very similar to an intermediate commit between `HEAD` and the working copy, so workflows that depend on it can be modeled using proper commits instead. Jujutsu has excellent support for moving changes between commits. [Details](#the-index). -* **No need for branch names (but they are supported).** Git lets you check out +- **No need for branch names (but they are supported).** Git lets you check out a commit without attaching a branch. It calls this state "detached HEAD". This is the normal state in Jujutsu (there's actually no way -- yet, at least -- to have an active branch). However, Jujutsu keeps track of all visible heads (leaves) of the commit graph, so the commits won't get lost or garbage-collected. -* **No current branch.** Git lets you check out a branch, making it the 'current +- **No current branch.** Git lets you check out a branch, making it the 'current branch', and new commits will automatically update the branch. This is necessary in Git because Git might otherwise lose track of the new commits. Jujutsu does not have a 'current branch'; instead, you update branches manually. For example, if you start work on top of a commit with a branch, new commits are created on top of the branch, then you issue a later command to update the branch. -* **Conflicts can be committed.** No commands fail because of merge conflicts. +- **Conflicts can be committed.** No commands fail because of merge conflicts. The conflicts are instead recorded in commits and you can resolve them later. [Details](conflicts.md). -* **Descendant commits are automatically rebased.** Whenever you rewrite a +- **Descendant commits are automatically rebased.** Whenever you rewrite a commit (e.g. by running `jj rebase`), all its descendants commits will automatically be rebased on top. Branches pointing to it will also get updated, and so will the working copy if it points to any of the rebased commits. -* **Branches are identified by their names (across remotes).** For example, if +- **Branches are identified by their names (across remotes).** For example, if you pull from a remote that has a `main` branch, you'll get a branch by that name in your local repo as well. If you then move it and push back to the remote, the `main` branch on the remote will be updated. - [Details](branches.md). -* **The operation log replaces reflogs.** The operation log is similar to + [Details](branches.md). +- **The operation log replaces reflogs.** The operation log is similar to reflogs, but is much more powerful. It keeps track of atomic updates to all refs at once (Jujutsu thus improves on Git's per-ref history much in the same way that Subversion improved on RCS's per-file history). The operation log powers e.g. the undo functionality. [Details](operation-log.md) -* **There's a single, virtual root commit.** Like Mercurial, Jujutsu has a +- **There's a single, virtual root commit.** Like Mercurial, Jujutsu has a virtual commit (with a hash consisting of only zeros) called the "root commit" (called the "null revision" in Mercurial). This commit is a common ancestor of all commits. That removes the awkward state Git calls the "unborn branch" state (which is the state a newly initialized Git repo is in), and related command-line flags (e.g. `git rebase --root`, `git checkout --orphan`). - ## The index Git's ["index"](https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified) has @@ -81,7 +79,6 @@ changes into the parent commit, which you might normally use choose which changes to move into the parent commit, or `jj squash ` to move a specific file. - ## Command equivalence table Note that all `jj` commands can be run on any commit (not just the working-copy diff --git a/docs/git-compatibility.md b/docs/git-compatibility.md index b533918705..ffb8655ad1 100644 --- a/docs/git-compatibility.md +++ b/docs/git-compatibility.md @@ -8,64 +8,62 @@ See `jj help git` for help about the `jj git` family of commands, and e.g. `jj help git push` for help about a specific command (use `jj git push -h` for briefer help). - ## Supported features The following list describes which Git features Jujutsu is compatible with. For a comparison with Git, including how workflows are different, see the [Git-comparison doc](git-comparison.md). -* **Configuration: Partial.** The only configuration from Git (e.g. in +- **Configuration: Partial.** The only configuration from Git (e.g. in `~/.gitconfig`) that's respected is the following. Feel free to file a bug if you miss any particular configuration options. - * The configuration of remotes (`[remote ""]`). - * `core.excludesFile` -* **Authentication: Partial.** Only `ssh-agent`, a password-less key ( + - The configuration of remotes (`[remote ""]`). + - `core.excludesFile` +- **Authentication: Partial.** Only `ssh-agent`, a password-less key ( only `~/.ssh/id_rsa`, `~/.ssh/id_ed25519` or `~/.ssh/id_ed25519_sk`), or a `credential.helper`. -* **Branches: Yes.** You can read more about +- **Branches: Yes.** You can read more about [how branches work in Jujutsu](branches.md) and [how they interoperate with Git](#branches). -* **Tags: Partial.** You can check out tagged commits by name (pointed to be +- **Tags: Partial.** You can check out tagged commits by name (pointed to be either annotated or lightweight tags), but you cannot create new tags. -* **.gitignore: Yes.** Ignores in `.gitignore` files are supported. So are +- **.gitignore: Yes.** Ignores in `.gitignore` files are supported. So are ignores in `.git/info/exclude` or configured via Git's `core.excludesfile` config. The `.gitignore` support uses a native implementation, so please - report a bug if you notice any difference compared to `git`. -* **.gitattributes: No.** There's [#53](https://github.com/martinvonz/jj/issues/53) + report a bug if you notice any difference compared to `git`. +- **.gitattributes: No.** There's [#53](https://github.com/martinvonz/jj/issues/53) about adding support for at least the `eol` attribute. -* **Hooks: No.** There's [#405](https://github.com/martinvonz/jj/issues/405) +- **Hooks: No.** There's [#405](https://github.com/martinvonz/jj/issues/405) specifically for providing the checks from https://pre-commit.com. -* **Merge commits: Yes.** Octopus merges (i.e. with more than 2 parents) are +- **Merge commits: Yes.** Octopus merges (i.e. with more than 2 parents) are also supported. -* **Detached HEAD: Yes.** Jujutsu supports anonymous branches, so this is a +- **Detached HEAD: Yes.** Jujutsu supports anonymous branches, so this is a natural state. -* **Orphan branch: Yes.** Jujutsu has a virtual root commit that appears as +- **Orphan branch: Yes.** Jujutsu has a virtual root commit that appears as parent of all commits Git would call "root commits". -* **Staging area: Kind of.** The staging area will be ignored. For example, +- **Staging area: Kind of.** The staging area will be ignored. For example, `jj diff` will show a diff from the Git HEAD to the working copy. There are [ways of fulfilling your use cases without a staging - area](https://github.com/martinvonz/jj/blob/main/docs/git-comparison.md#the-index). -* **Garbage collection: Yes.** It should be safe to run `git gc` in the Git + area](https://github.com/martinvonz/jj/blob/main/docs/git-comparison.md#the-index). +- **Garbage collection: Yes.** It should be safe to run `git gc` in the Git repo, but it's not tested, so it's probably a good idea to make a backup of the whole workspace first. There's [no garbage collection and repacking of Jujutsu's own data structures yet](https://github.com/martinvonz/jj/issues/12), however. -* **Bare repositories: Yes.** You can use `jj git init --git-repo=` to +- **Bare repositories: Yes.** You can use `jj git init --git-repo=` to create a repo backed by a bare Git repo. -* **Submodules: No.** They will not show up in the working copy, but they will +- **Submodules: No.** They will not show up in the working copy, but they will not be lost either. -* **Partial clones: No.** We use the [libgit2](https://libgit2.org/) library, +- **Partial clones: No.** We use the [libgit2](https://libgit2.org/) library, which [doesn't have support for partial clones](https://github.com/libgit2/libgit2/issues/5564). -* **Shallow clones: No.** We use the [libgit2](https://libgit2.org/) library, +- **Shallow clones: No.** We use the [libgit2](https://libgit2.org/) library, which [doesn't have support for shallow clones](https://github.com/libgit2/libgit2/issues/3058). -* **git-worktree: No.** However, there's native support for multiple working +- **git-worktree: No.** However, there's native support for multiple working copies backed by a single repo. See the `jj workspace` family of commands. -* **Sparse checkouts: No.** However, there's native support for sparse +- **Sparse checkouts: No.** However, there's native support for sparse checkouts. See the `jj sparse` command. -* **Signed commits: No.** ([#58](https://github.com/martinvonz/jj/issues/58)) -* **Git LFS: No.** ([#80](https://github.com/martinvonz/jj/issues/80)) - +- **Signed commits: No.** ([#58](https://github.com/martinvonz/jj/issues/58)) +- **Git LFS: No.** ([#80](https://github.com/martinvonz/jj/issues/80)) ## Creating an empty repo @@ -74,7 +72,6 @@ the command creates a Jujutsu repo, it will have a `.jj/` directory. The underlying Git repo will be inside of that directory (currently in `.jj/repo/store/git/`). - ## Creating a repo backed by an existing Git repo To create a Jujutsu repo backed by a Git repo you already have on disk, use @@ -92,7 +89,6 @@ To create a Jujutsu repo from a remote Git URL, use `jj git clone https://github.com/octocat/Hello-World` will clone GitHub's "Hello-World" repo into a directory by the same name. - ## Co-located Jujutsu/Git repos A "co-located" Jujutsu repo is a hybrid Jujutsu/Git repo. These can be created @@ -119,40 +115,40 @@ git refs" operation. There are a few downsides to this mode of operation. Generally, using co-located repos may require you to deal with more involved Jujutsu and Git concepts. -* Interleaving `jj` and `git` commands increases the chance of confusing branch +- Interleaving `jj` and `git` commands increases the chance of confusing branch conflicts or [conflicted (AKA divergent) change ids](glossary.md#divergent-change). These never lose data, but can be annoying. - Such interleaving can happen unknowingly. For example, some IDEs can cause + Such interleaving can happen unknowingly. For example, some IDEs can cause it because they automatically run `git fetch` in the background from time to time. -* In co-located repos with a very large number of branches or other refs, `jj` +- In co-located repos with a very large number of branches or other refs, `jj` commands can get noticeably slower because of the automatic `jj git import` executed on each command. This can be mitigated by occasionally running `jj util - gc` to speed up the import (that command includes packing the Git refs). +gc` to speed up the import (that command includes packing the Git refs). -* Git tools will have trouble with revisions that contain conflicted files. While +- Git tools will have trouble with revisions that contain conflicted files. While `jj` renders these files with conflict markers in the working copy, they are stored in a non-human-readable fashion inside the repo. Git tools will often see this non-human-readable representation. -* When a `jj` branch is conflicted, the position of the branch in the Git repo +- When a `jj` branch is conflicted, the position of the branch in the Git repo will disagree with one or more of the conflicted positions. The state of that branch in git will be labeled as though it belongs to a remote named "git", e.g. `branch@git`. -* Jujutsu will ignore Git's staging area. It will not understand merge conflicts +- Jujutsu will ignore Git's staging area. It will not understand merge conflicts as Git represents them, unfinished `git rebase` states, as well as other less common states a Git repository can be in. -* Colocated repositories are less resilient to +- Colocated repositories are less resilient to [concurrency](technical/concurrency.md#syncing-with-rsync-nfs-dropbox-etc) issues if you share the repo using an NFS filesystem or Dropbox. In general, such use of Jujutsu is not currently thoroughly tested. -* There may still be bugs when interleaving mutating `jj` and `git` commands, +- There may still be bugs when interleaving mutating `jj` and `git` commands, usually having to do with a branch pointer ending up in the wrong place. We are working on the known ones, and are not aware of any major ones. Please report any new ones you find, or if any of the known bugs are less minor than @@ -183,7 +179,6 @@ appreciate feedback and bug reports. TODO: Describe how branches are mapped - ## Format mapping details Paths are assumed to be UTF-8. I have no current plans to support paths with diff --git a/docs/github.md b/docs/github.md index a15e45e15b..d0a6874bb0 100644 --- a/docs/github.md +++ b/docs/github.md @@ -147,10 +147,10 @@ If your project prefers that you keep commits clean, you can do that by doing something like this: ```shell -$ # Create a new commit on top of the second-to-last commit in `your-feature`, -$ # as reviewers requested a fix there. +$ # Create a new commit on top of the second-to-last commit in `your-feature`, +$ # as reviewers requested a fix there. $ jj new your-feature- # NOTE: the trailing hyphen is not a typo! -$ # Address the comments by updating the code. Then review the changes. +$ # Address the comments by updating the code. Then review the changes. $ jj diff $ # Squash the changes into the parent commit $ jj squash diff --git a/docs/index.md b/docs/index.md index 2babcc7d6f..a6ec610388 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,6 +3,7 @@ ## Welcome to `jj`'s documentation website! + The complete list of the available documentation pages is located in the sidebar on the left of the page. The sidebar may be hidden; if so, you can open it either by widening your browser window or by clicking diff --git a/docs/install-and-setup.md b/docs/install-and-setup.md index 3e91e9d3bd..13911e44f4 100644 --- a/docs/install-and-setup.md +++ b/docs/install-and-setup.md @@ -1,6 +1,5 @@ # Installation and setup - ## Installation ### Download pre-built binaries for a release @@ -25,10 +24,10 @@ cargo binstall --strategies crate-meta-data jj-cli Without the `--strategies` option, you may get equivalent binaries that should be compiled from the same source code. - ### Linux #### Arch Linux + You can install the `jujutsu` package from the [official extra repository](https://archlinux.org/packages/extra/x86_64/jujutsu/): ``` @@ -120,7 +119,6 @@ or: cargo install --locked --bin jj jj-cli ``` - #### Homebrew If you use Homebrew, you can run: @@ -156,7 +154,6 @@ or: cargo install --locked --bin jj jj-cli --features vendored-openssl ``` - ## Initial configuration You may want to configure your name and email so commits are made in your name. @@ -196,7 +193,7 @@ jj util completion fish | source ```nu jj util completion nushell | save completions-jj.nu -use completions-jj.nu * # Or `source completions-jj.nu` +use completions-jj.nu * # Or `source completions-jj.nu` ``` ### Xonsh diff --git a/docs/operation-log.md b/docs/operation-log.md index 81a9375c9e..2e8bc22250 100644 --- a/docs/operation-log.md +++ b/docs/operation-log.md @@ -1,6 +1,5 @@ # Operation log - ## Introduction Jujutsu records each operation that modifies the repo in the "operation log". @@ -22,9 +21,8 @@ operation. The following operators are supported: -* `x-`: Parents of `x` (e.g. `@-`) -* `x+`: Children of `x` - +- `x-`: Parents of `x` (e.g. `@-`) +- `x+`: Children of `x` ## Concurrent operations @@ -43,7 +41,6 @@ then also update the contents of the change (maybe because you had forgotten the editor). When you eventually close your editor, the command will succeed and e.g. `jj log` will indicate that the change has diverged. - ## Loading an old version of the repo The top-level `--at-operation/--at-op` option allows you to load the repo at a diff --git a/docs/related-work.md b/docs/related-work.md index 5ef2fb8069..bf640d84ae 100644 --- a/docs/related-work.md +++ b/docs/related-work.md @@ -2,24 +2,24 @@ Similar tools: -* [git-branchless](https://github.com/arxanas/git-branchless): Helps you use a +- [git-branchless](https://github.com/arxanas/git-branchless): Helps you use a branchless workflow in your Git repo. Supports anonymous branching, undo, and faster rebase (`git move`). Under heavy development and quickly gaining new features. -* [Sapling](https://sapling-scm.com/): A heavily modified fork of +- [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). See [how it is different from Jujutsu](sapling-comparison.md). -* [GitUp](https://gitup.co/): A Mac-only GUI for Git. Like Jujutsu, supports +- [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). -* [Gitless](https://gitless.com/): Another attempt at providing a simpler +- [Gitless](https://gitless.com/): Another attempt at providing a simpler interface for Git. Like Jujutsu, does not have an "index"/"staging area" concept. Also doesn't move the working-copy changes between branches (which we do simply as a consequence of making the working copy a commit). -* [Breezy](https://www.breezy-vcs.org/): Another VCS that's similar in that it +- [Breezy](https://www.breezy-vcs.org/): Another VCS that's similar in that it has multiple storage backends, including its own format as well as .git support. -* [Sturdy](https://getsturdy.com/): A Git backed GUI that eliminates local and +- [Sturdy](https://getsturdy.com/): A Git backed GUI that eliminates local and remote as well as the idea of an "index"/"staging area". diff --git a/docs/revsets.md b/docs/revsets.md index 1e14ea199a..248929bae9 100644 --- a/docs/revsets.md +++ b/docs/revsets.md @@ -50,23 +50,23 @@ Jujutsu attempts to resolve a symbol in the following order: The following operators are supported. `x` and `y` below can be any revset, not only symbols. -* `x & y`: Revisions that are in both `x` and `y`. -* `x | y`: Revisions that are in either `x` or `y` (or both). -* `x ~ y`: Revisions that are in `x` but not in `y`. -* `~x`: Revisions that are not in `x`. -* `x-`: Parents of `x`. -* `x+`: Children of `x`. -* `::x`: Ancestors of `x`, including the commits in `x` itself. -* `x::`: Descendants of `x`, including the commits in `x` itself. -* `x::y`: Descendants of `x` that are also ancestors of `y`. Equivalent - to `x:: & ::y`. This is what `git log` calls `--ancestry-path x..y`. -* `::`: All visible commits in the repo. Equivalent to `all()`. -* `x..y`: Ancestors of `y` that are not also ancestors of `x`. Equivalent to +- `x & y`: Revisions that are in both `x` and `y`. +- `x | y`: Revisions that are in either `x` or `y` (or both). +- `x ~ y`: Revisions that are in `x` but not in `y`. +- `~x`: Revisions that are not in `x`. +- `x-`: Parents of `x`. +- `x+`: Children of `x`. +- `::x`: Ancestors of `x`, including the commits in `x` itself. +- `x::`: Descendants of `x`, including the commits in `x` itself. +- `x::y`: Descendants of `x` that are also ancestors of `y`. Equivalent + to `x:: & ::y`. This is what `git log` calls `--ancestry-path x..y`. +- `::`: All visible commits in the repo. Equivalent to `all()`. +- `x..y`: Ancestors of `y` that are not also ancestors of `x`. Equivalent to `::y ~ ::x`. This is what `git log` calls `x..y` (i.e. the same as we call it). -* `..x`: Ancestors of `x`, including the commits in `x` itself, but excluding +- `..x`: Ancestors of `x`, including the commits in `x` itself, but excluding the root commit. Equivalent to `::x ~ root()`. -* `x..`: Revisions that are not ancestors of `x`. -* `..`: All visible commits in the repo, but excluding the root commit. +- `x..`: Revisions that are not ancestors of `x`. +- `..`: All visible commits in the repo, but excluding the root commit. Equivalent to `~root()`. You can use parentheses to control evaluation order, such as `(x & y) | z` or @@ -77,33 +77,33 @@ You can use parentheses to control evaluation order, such as `(x & y) | z` or You can also specify revisions by using functions. Some functions take other revsets (expressions) as arguments. -* `parents(x)`: Same as `x-`. +- `parents(x)`: Same as `x-`. -* `children(x)`: Same as `x+`. +- `children(x)`: Same as `x+`. -* `ancestors(x[, depth])`: `ancestors(x)` is the same as `::x`. +- `ancestors(x[, depth])`: `ancestors(x)` is the same as `::x`. `ancestors(x, depth)` returns the ancestors of `x` limited to the given `depth`. -* `descendants(x)`: Same as `x::`. +- `descendants(x)`: Same as `x::`. -* `reachable(srcs, domain)`: All commits reachable from `srcs` within +- `reachable(srcs, domain)`: All commits reachable from `srcs` within `domain`, traversing all parent and child edges. -* `connected(x)`: Same as `x::x`. Useful when `x` includes several commits. +- `connected(x)`: Same as `x::x`. Useful when `x` includes several commits. -* `all()`: All visible commits in the repo. +- `all()`: All visible commits in the repo. -* `none()`: No commits. This function is rarely useful; it is provided for +- `none()`: No commits. This function is rarely useful; it is provided for completeness. -* `branches([pattern])`: All local branch targets. If `pattern` is specified, +- `branches([pattern])`: All local branch targets. If `pattern` is specified, this selects the branches whose name match the given [string pattern](#string-patterns). For example, `branches(push)` would match the branches `push-123` and `repushed` but not the branch `main`. If a branch is in a conflicted state, all its possible targets are included. -* `remote_branches([branch_pattern[, [remote=]remote_pattern]])`: All remote +- `remote_branches([branch_pattern[, [remote=]remote_pattern]])`: All remote branch targets across all remotes. If just the `branch_pattern` is specified, the branches whose names match the given [string pattern](#string-patterns) across all remotes are selected. If both @@ -118,73 +118,73 @@ revsets (expressions) as arguments. While Git-tracking branches can be selected by `@git`, these branches aren't included in `remote_branches()`. -* `tags()`: All tag targets. If a tag is in a conflicted state, all its +- `tags()`: All tag targets. If a tag is in a conflicted state, all its possible targets are included. -* `git_refs()`: All Git ref targets as of the last import. If a Git ref +- `git_refs()`: All Git ref targets as of the last import. If a Git ref is in a conflicted state, all its possible targets are included. -* `git_head()`: The Git `HEAD` target as of the last import. Equivalent to +- `git_head()`: The Git `HEAD` target as of the last import. Equivalent to `present(HEAD@git)`. -* `visible_heads()`: All visible heads (same as `heads(all())`). +- `visible_heads()`: All visible heads (same as `heads(all())`). -* `root()`: The virtual commit that is the oldest ancestor of all other commits. +- `root()`: The virtual commit that is the oldest ancestor of all other commits. -* `heads(x)`: Commits in `x` that are not ancestors of other commits in `x`. +- `heads(x)`: Commits in `x` that are not ancestors of other commits in `x`. Note that this is different from [Mercurial's](https://repo.mercurial-scm.org/hg/help/revsets) `heads(x)` function, which is equivalent to `x ~ x-`. -* `roots(x)`: Commits in `x` that are not descendants of other commits in `x`. +- `roots(x)`: Commits in `x` that are not descendants of other commits in `x`. Note that this is different from [Mercurial's](https://repo.mercurial-scm.org/hg/help/revsets) `roots(x)` function, which is equivalent to `x ~ x+`. -* `latest(x[, count])`: Latest `count` commits in `x`, based on committer +- `latest(x[, count])`: Latest `count` commits in `x`, based on committer timestamp. The default `count` is 1. -* `merges()`: Merge commits. +- `merges()`: Merge commits. -* `description(pattern)`: Commits that have a description matching the given +- `description(pattern)`: Commits that have a description matching the given [string pattern](#string-patterns). -* `author(pattern)`: Commits with the author's name or email matching the given +- `author(pattern)`: Commits with the author's name or email matching the given [string pattern](#string-patterns). -* `mine()`: Commits where the author's email matches the email of the current +- `mine()`: Commits where the author's email matches the email of the current user. -* `committer(pattern)`: Commits with the committer's name or email matching the -given [string pattern](#string-patterns). +- `committer(pattern)`: Commits with the committer's name or email matching the + given [string pattern](#string-patterns). -* `empty()`: Commits modifying no files. This also includes `merges()` without +- `empty()`: Commits modifying no files. This also includes `merges()` without user modifications and `root()`. -* `file(pattern[, pattern]...)`: Commits modifying paths matching one of the +- `file(pattern[, pattern]...)`: Commits modifying paths matching one of the given [file patterns](filesets.md#file-patterns). Paths are relative to the directory `jj` was invoked from. A directory name will match all files in that directory and its subdirectories. For example, `file(foo)` will match files `foo`, `foo/bar`, `foo/bar/baz`. - It will *not* match `foobar` or `bar/foo`. + It will _not_ match `foobar` or `bar/foo`. -* `conflict()`: Commits with conflicts. +- `conflict()`: Commits with conflicts. -* `present(x)`: Same as `x`, but evaluated to `none()` if any of the commits +- `present(x)`: Same as `x`, but evaluated to `none()` if any of the commits in `x` doesn't exist (e.g. is an unknown branch name.) -* `working_copies()`: The working copy commits across all the workspaces. +- `working_copies()`: The working copy commits across all the workspaces. ## String patterns Functions that perform string matching support the following pattern syntax: -* `"string"`, or `string` (the quotes are optional), or `substring:"string"`: +- `"string"`, or `string` (the quotes are optional), or `substring:"string"`: Matches strings that contain `string`. -* `exact:"string"`: Matches strings exactly equal to `string`. -* `glob:"pattern"`: Matches strings with Unix-style shell [wildcard +- `exact:"string"`: Matches strings exactly equal to `string`. +- `glob:"pattern"`: Matches strings with Unix-style shell [wildcard `pattern`](https://docs.rs/glob/latest/glob/struct.Pattern.html). ## Aliases @@ -203,11 +203,11 @@ For example: ### Built-in Aliases The following aliases are built-in and used for certain operations. These functions -are defined as aliases in order to allow you to overwrite them as needed. +are defined as aliases in order to allow you to overwrite them as needed. See [revsets.toml](https://github.com/martinvonz/jj/blob/main/cli/src/config/revsets.toml) for a comprehensive list. -* `trunk()`: Resolves to the head commit for the trunk branch of the remote +- `trunk()`: Resolves to the head commit for the trunk branch of the remote named `origin` or `upstream`. The branches `main`, `master`, and `trunk` are tried. If more than one potential trunk commit exists, the newest one is chosen. If none of the branches exist, the revset evaluates to `root()`. @@ -220,20 +220,19 @@ for a comprehensive list. 'trunk()' = 'your-branch@your-remote' ``` -* `immutable_heads()`: Resolves to `trunk() | tags()` by default. See +- `immutable_heads()`: Resolves to `trunk() | tags()` by default. See [here](config.md#set-of-immutable-commits) for details. -* `immutable()`: The set of commits that `jj` treats as immutable. This is +- `immutable()`: The set of commits that `jj` treats as immutable. This is equivalent to `::(immutable_heads() | root())`. Note that modifying this will - *not* change whether a commit is immutable. To do that, edit + _not_ change whether a commit is immutable. To do that, edit `immutable_heads()`. -* `mutable()`: The set of commits that `jj` treats as mutable. This is +- `mutable()`: The set of commits that `jj` treats as mutable. This is equivalent to `~immutable()`. Note that modifying this will - *not* change whether a commit is immutable. To do that, edit + _not_ change whether a commit is immutable. To do that, edit `immutable_heads()`. - ## The `all:` modifier Certain commands (such as `jj rebase`) can take multiple revset arguments, and @@ -253,7 +252,7 @@ patterms](#string-patterns). For example, `jj rebase -r w -d xyz+` will rebase `w` on top of the child of `xyz` as long as `xyz` has exactly one child. -If `xyz` has more than one child, the `all:` modifier is *not* specified, and +If `xyz` has more than one child, the `all:` modifier is _not_ specified, and `ui.always-allow-large-revsets` is `false` (the default), `jj rebase -r w -d xyz+` will return an error. @@ -308,7 +307,6 @@ jj log -r 'tags() | branches()' Show local commits leading up to the working copy, as well as descendants of those commits: - ``` jj log -r '(remote_branches()..@)::' ``` diff --git a/docs/sapling-comparison.md b/docs/sapling-comparison.md index de1c6b9803..3f7bc63440 100644 --- a/docs/sapling-comparison.md +++ b/docs/sapling-comparison.md @@ -8,44 +8,44 @@ 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 +- 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) +- 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 +- **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 + - 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 + - Simpler and more consistent CLI because the working copy is treated like any other commit. -* **Conflicts:** Like most VCSs, Sapling requires the user to +- **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 + - 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. + - 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 +- **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 @@ -56,15 +56,15 @@ Here is a list of some differences between jj and Sapling. 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 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, +- **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 +- **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 diff --git a/docs/technical/architecture.md b/docs/technical/architecture.md index b6f0bf5945..fa47705db2 100644 --- a/docs/technical/architecture.md +++ b/docs/technical/architecture.md @@ -17,8 +17,9 @@ input/output is handled by the CLI crate [^1]. Since the library crate is meant to usable in a server, it also cannot read configuration from the user's home directory, or from user-specific environment variables. -[^1]: There are a few exceptions, such as for messages printed during automatic -upgrades of the repo format +[^1]: + There are a few exceptions, such as for messages printed during automatic + upgrades of the repo format A lot of thought has gone into making the library crate's API easy to use, but not much has gone into "details" such as which collection types are used, or diff --git a/docs/technical/concurrency.md b/docs/technical/concurrency.md index 0993daf885..3e9d26c27b 100644 --- a/docs/technical/concurrency.md +++ b/docs/technical/concurrency.md @@ -3,7 +3,7 @@ ## Introduction Concurrent editing is a key feature of DVCSs -- that's why they're called -*Distributed* Version Control Systems. A DVCS that didn't let users edit files +_Distributed_ Version Control Systems. A DVCS that didn't let users edit files and create commits on separate machines at the same time wouldn't be much of a distributed VCS. @@ -20,7 +20,7 @@ the same whether they're made locally or remotely. One problem with using lock files is that they don't work when the clone is in a distributed file system. Most clones are of course not stored in distributed -file systems, but it is a *big* problem when they are (Mercurial repos +file systems, but it is a _big_ problem when they are (Mercurial repos frequently get corrupted, for example). Another problem with using lock files is related to complexity of @@ -60,7 +60,6 @@ should be safe, concurrent modification of a repository from different computers might conceivably lose some branch pointers. Note that, unlike in pure Git, losing a branch pointer does not lead to losing commits. - ## Operation log The most important piece in the lock-free design is the "operation log". That is diff --git a/docs/technical/conflicts.md b/docs/technical/conflicts.md index 7ac9a664c6..eeb31a0653 100644 --- a/docs/technical/conflicts.md +++ b/docs/technical/conflicts.md @@ -20,10 +20,10 @@ always be an odd number of trees linked from the commit. You can think of the first tree as a start tree, and the subsequent pairs of trees to apply the diff between onto the start. Examples: -* If the commit has trees A, B, C, D, and E it means that the contents should be +- If the commit has trees A, B, C, D, and E it means that the contents should be calculated as A+(C-B)+(E-D). -* A three-way merge between A and C with B as base can be represented as a -commit with trees A, B, and C, also known as A+(C-B). +- A three-way merge between A and C with B as base can be represented as a + commit with trees A, B, and C, also known as A+(C-B). The resulting tree contents is calculated on demand. Note that we often don't need to merge the entire tree. For example, when checking out a commit in the diff --git a/docs/templates.md b/docs/templates.md index fa655e1376..2a7db4cb95 100644 --- a/docs/templates.md +++ b/docs/templates.md @@ -28,32 +28,32 @@ type](#operation-type) are available as keywords. For example, The following operators are supported. -* `x.f()`: Method call. -* `-x`: Negate integer value. -* `!x`: Logical not. -* `x && y`: Logical and, short-circuiting. -* `x || y`: Logical or, short-circuiting. -* `x ++ y`: Concatenate `x` and `y` templates. +- `x.f()`: Method call. +- `-x`: Negate integer value. +- `!x`: Logical not. +- `x && y`: Logical and, short-circuiting. +- `x || y`: Logical or, short-circuiting. +- `x ++ y`: Concatenate `x` and `y` templates. ## Global functions The following functions are defined. -* `fill(width: Integer, content: Template) -> Template`: Fill lines at +- `fill(width: Integer, content: Template) -> Template`: Fill lines at the given `width`. -* `indent(prefix: Template, content: Template) -> Template`: Indent +- `indent(prefix: Template, content: Template) -> Template`: Indent non-empty lines by the given `prefix`. -* `label(label: Template, content: Template) -> Template`: Apply label to +- `label(label: Template, content: Template) -> Template`: Apply label to the content. The `label` is evaluated as a space-separated string. -* `if(condition: Boolean, then: Template[, else: Template]) -> Template`: +- `if(condition: Boolean, then: Template[, else: Template]) -> Template`: Conditionally evaluate `then`/`else` template content. -* `coalesce(content: Template...) -> Template`: Returns the first **non-empty** +- `coalesce(content: Template...) -> Template`: Returns the first **non-empty** content. -* `concat(content: Template...) -> Template`: +- `concat(content: Template...) -> Template`: Same as `content_1 ++ ... ++ content_n`. -* `separate(separator: Template, content: Template...) -> Template`: +- `separate(separator: Template, content: Template...) -> Template`: Insert separator between **non-empty** contents. -* `surround(prefix: Template, suffix: Template, content: Template) -> Template`: +- `surround(prefix: Template, suffix: Template, content: Template) -> Template`: Surround **non-empty** content with texts such as parentheses. ## Types @@ -66,42 +66,42 @@ No methods are defined. Can be constructed with `false` or `true` literal. This type cannot be printed. The following methods are defined. -* `description() -> String` -* `change_id() -> ChangeId` -* `commit_id() -> CommitId` -* `parents() -> List` -* `author() -> Signature` -* `committer() -> Signature` -* `mine() -> Boolean`: Commits where the author's email matches the email of the current +- `description() -> String` +- `change_id() -> ChangeId` +- `commit_id() -> CommitId` +- `parents() -> List` +- `author() -> Signature` +- `committer() -> Signature` +- `mine() -> Boolean`: Commits where the author's email matches the email of the current user. -* `working_copies() -> String`: For multi-workspace repository, indicate +- `working_copies() -> String`: For multi-workspace repository, indicate working-copy commit as `@`. -* `current_working_copy() -> Boolean`: True for the working-copy commit of the +- `current_working_copy() -> Boolean`: True for the working-copy commit of the current workspace. -* `branches() -> List`: Local and remote branches pointing to the commit. +- `branches() -> List`: Local and remote branches pointing to the commit. A tracking remote branch will be included only if its target is different from the local one. -* `local_branches() -> List`: All local branches pointing to the commit. -* `remote_branches() -> List`: All remote branches pointing to the commit. -* `tags() -> List` -* `git_refs() -> List` -* `git_head() -> Option` -* `divergent() -> Boolean`: True if the commit's change id corresponds to multiple +- `local_branches() -> List`: All local branches pointing to the commit. +- `remote_branches() -> List`: All remote branches pointing to the commit. +- `tags() -> List` +- `git_refs() -> List` +- `git_head() -> Option` +- `divergent() -> Boolean`: True if the commit's change id corresponds to multiple visible commits. -* `hidden() -> Boolean`: True if the commit is not visible (a.k.a. abandoned). -* `immutable() -> Boolean`: True if the commit is included in [the set of +- `hidden() -> Boolean`: True if the commit is not visible (a.k.a. abandoned). +- `immutable() -> Boolean`: True if the commit is included in [the set of immutable commits](config.md#set-of-immutable-commits). -* `contained_in(revset: String) -> Boolean`: True if the commit is included in [the provided revset](revsets.md). -* `conflict() -> Boolean`: True if the commit contains merge conflicts. -* `empty() -> Boolean`: True if the commit modifies no files. -* `root() -> Boolean`: True if the commit is the root commit. +- `contained_in(revset: String) -> Boolean`: True if the commit is included in [the provided revset](revsets.md). +- `conflict() -> Boolean`: True if the commit contains merge conflicts. +- `empty() -> Boolean`: True if the commit modifies no files. +- `root() -> Boolean`: True if the commit is the root commit. ### CommitId / ChangeId type The following methods are defined. -* `.short([len: Integer]) -> String` -* `.shortest([min_len: Integer]) -> ShortestIdPrefix`: Shortest unique prefix. +- `.short([len: Integer]) -> String` +- `.shortest([min_len: Integer]) -> ShortestIdPrefix`: Shortest unique prefix. ### Integer type @@ -112,36 +112,36 @@ No methods are defined. A list can be implicitly converted to `Boolean`. The following methods are defined. -* `.len() -> Integer`: Number of elements in the list. -* `.join(separator: Template) -> Template`: Concatenate elements with +- `.len() -> Integer`: Number of elements in the list. +- `.join(separator: Template) -> Template`: Concatenate elements with the given `separator`. -* `.map(|item| expression) -> ListTemplate`: Apply template `expression` +- `.map(|item| expression) -> ListTemplate`: Apply template `expression` to each element. Example: `parents.map(|c| c.commit_id().short())` ### ListTemplate type The following methods are defined. See also the `List` type. -* `.join(separator: Template) -> Template` +- `.join(separator: Template) -> Template` ### Operation type This type cannot be printed. The following methods are defined. -* `current_operation() -> Boolean` -* `description() -> String` -* `id() -> OperationId` -* `tags() -> String` -* `time() -> TimestampRange` -* `user() -> String` -* `snapshot() -> Boolean`: True if the operation is a snapshot operation. -* `root() -> Boolean`: True if the operation is the root operation. +- `current_operation() -> Boolean` +- `description() -> String` +- `id() -> OperationId` +- `tags() -> String` +- `time() -> TimestampRange` +- `user() -> String` +- `snapshot() -> Boolean`: True if the operation is a snapshot operation. +- `root() -> Boolean`: True if the operation is the root operation. ### OperationId type The following methods are defined. -* `.short([len: Integer]) -> String` +- `.short([len: Integer]) -> String` ### Option type @@ -153,69 +153,69 @@ invoked. If not set, an error will be reported inline on method call. The following methods are defined. -* `.name() -> String`: Local branch or tag name. -* `.remote() -> String`: Remote name or empty if this is a local ref. -* `.present() -> Boolean`: True if the ref points to any commit. -* `.conflict() -> Boolean`: True if [the branch or tag is +- `.name() -> String`: Local branch or tag name. +- `.remote() -> String`: Remote name or empty if this is a local ref. +- `.present() -> Boolean`: True if the ref points to any commit. +- `.conflict() -> Boolean`: True if [the branch or tag is conflicted](branches.md#conflicts). -* `.normal_target() -> Option`: Target commit if the ref is not +- `.normal_target() -> Option`: Target commit if the ref is not conflicted and points to a commit. -* `.removed_targets() -> List`: Old target commits if conflicted. -* `.added_targets() -> List`: New target commits. The list usually +- `.removed_targets() -> List`: Old target commits if conflicted. +- `.added_targets() -> List`: New target commits. The list usually contains one "normal" target. -* `.tracked() -> Boolean`: True if the ref is tracked by a local ref. The local +- `.tracked() -> Boolean`: True if the ref is tracked by a local ref. The local ref might have been deleted (but not pushed yet.) -* `.tracking_present() -> Boolean`: True if the ref is tracked by a local ref, - and if the local ref points to any commit. -* `.tracking_ahead_count() -> SizeHint`: Number of commits ahead of the tracking +- `.tracking_present() -> Boolean`: True if the ref is tracked by a local ref, + and if the local ref points to any commit. +- `.tracking_ahead_count() -> SizeHint`: Number of commits ahead of the tracking local ref. -* `.tracking_behind_count() -> SizeHint`: Number of commits behind of the +- `.tracking_behind_count() -> SizeHint`: Number of commits behind of the tracking local ref. ### ShortestIdPrefix type The following methods are defined. -* `.prefix() -> String` -* `.rest() -> String` -* `.upper() -> ShortestIdPrefix` -* `.lower() -> ShortestIdPrefix` +- `.prefix() -> String` +- `.rest() -> String` +- `.upper() -> ShortestIdPrefix` +- `.lower() -> ShortestIdPrefix` ### Signature type The following methods are defined. -* `.name() -> String` -* `.email() -> String` -* `.username() -> String` -* `.timestamp() -> Timestamp` +- `.name() -> String` +- `.email() -> String` +- `.username() -> String` +- `.timestamp() -> Timestamp` ### SizeHint type This type cannot be printed. The following methods are defined. -* `.lower() -> Integer`: Lower bound. -* `.upper() -> Option`: Upper bound if known. -* `.exact() -> Option`: Exact value if upper bound is known and it +- `.lower() -> Integer`: Lower bound. +- `.upper() -> Option`: Upper bound if known. +- `.exact() -> Option`: Exact value if upper bound is known and it equals to the lower bound. -* `.zero() -> Boolean`: True if upper bound is known and is `0`. +- `.zero() -> Boolean`: True if upper bound is known and is `0`. ### String type A string can be implicitly converted to `Boolean`. The following methods are defined. -* `.len() -> Integer`: Length in UTF-8 bytes. -* `.contains(needle: Template) -> Boolean` -* `.first_line() -> String` -* `.lines() -> List`: Split into lines excluding newline characters. -* `.upper() -> String` -* `.lower() -> String` -* `.starts_with(needle: Template) -> Boolean` -* `.ends_with(needle: Template) -> Boolean` -* `.remove_prefix(needle: Template) -> String`: Removes the passed prefix, if present -* `.remove_suffix(needle: Template) -> String`: Removes the passed suffix, if present -* `.substr(start: Integer, end: Integer) -> String`: Extract substring. The +- `.len() -> Integer`: Length in UTF-8 bytes. +- `.contains(needle: Template) -> Boolean` +- `.first_line() -> String` +- `.lines() -> List`: Split into lines excluding newline characters. +- `.upper() -> String` +- `.lower() -> String` +- `.starts_with(needle: Template) -> Boolean` +- `.ends_with(needle: Template) -> Boolean` +- `.remove_prefix(needle: Template) -> String`: Removes the passed prefix, if present +- `.remove_suffix(needle: Template) -> String`: Removes the passed suffix, if present +- `.substr(start: Integer, end: Integer) -> String`: Extract substring. The `start`/`end` indices should be specified in UTF-8 bytes. Negative values count from the end of the string. @@ -224,12 +224,12 @@ defined. String literals must be surrounded by single or double quotes (`'` or `"`). A double-quoted string literal supports the following escape sequences: -* `\"`: double quote -* `\\`: backslash -* `\t`: horizontal tab -* `\r`: carriage return -* `\n`: new line -* `\0`: null +- `\"`: double quote +- `\\`: backslash +- `\t`: horizontal tab +- `\r`: carriage return +- `\n`: new line +- `\0`: null Other escape sequences are not supported. Any UTF-8 characters are allowed inside a string literal, with two exceptions: unescaped `"`-s and uses of `\` @@ -246,19 +246,19 @@ Most types can be implicitly converted to `Template`. No methods are defined. The following methods are defined. -* `.ago() -> String`: Format as relative timestamp. -* `.format(format: String) -> String`: Format with [the specified strftime-like +- `.ago() -> String`: Format as relative timestamp. +- `.format(format: String) -> String`: Format with [the specified strftime-like format string](https://docs.rs/chrono/latest/chrono/format/strftime/). -* `.utc() -> Timestamp`: Convert timestamp into UTC timezone. -* `.local() -> Timestamp`: Convert timestamp into local timezone. +- `.utc() -> Timestamp`: Convert timestamp into UTC timezone. +- `.local() -> Timestamp`: Convert timestamp into local timezone. ### TimestampRange type The following methods are defined. -* `.start() -> Timestamp` -* `.end() -> Timestamp` -* `.duration() -> String` +- `.start() -> Timestamp` +- `.end() -> Timestamp` +- `.duration() -> String` ## Configuration diff --git a/docs/testimonials.md b/docs/testimonials.md index 5ab6860086..449a34c753 100644 --- a/docs/testimonials.md +++ b/docs/testimonials.md @@ -6,7 +6,7 @@ practice. In order to provide some motivation, we've collected a number of real, 100% authentic testimonials — from our loving users, our silly developers — all to tip the scales and get you on our side! -## What the users have to say +## What the users have to say > I've spent many years of my career working on version control. What I like > most about Jujutsu is how it has non-obvious solutions to UX problems that @@ -37,18 +37,18 @@ practice. In order to provide some motivation, we've collected a number of real, > It's so rare that a solution attacks the innermost core of a problem so > thoroughly, I genuinely feel blessed to be in its presence. And also a bit > vindicated in not even trying to learn to use any of the tools that felt like -> more crutches stacked upon a sand castle +> more crutches stacked upon a sand castle — Anonymous user, speaking from the shadows -> It's the easiest time I've ever had learning a tool this deeply this quickly, -> because of the ability to experiment and undo, instead of triple-checking +> It's the easiest time I've ever had learning a tool this deeply this quickly, +> because of the ability to experiment and undo, instead of triple-checking > before trying a new scary command. — Scott Olson, advanced Git user and now a Jujutsu user -> I initially started to use Jujutsu for personal repos, and it has quickly -> gone from "neat, let's try this more" to "very neat, added to my permanent +> I initially started to use Jujutsu for personal repos, and it has quickly +> gone from "neat, let's try this more" to "very neat, added to my permanent > config and automatically installed for new machines". — Poliorcetics, on GitHub @@ -59,7 +59,7 @@ practice. In order to provide some motivation, we've collected a number of real, — jyn514, Rust contributor -> Jujutsu is pretty cool, you can even keep most of your existing workflows +> Jujutsu is pretty cool, you can even keep most of your existing workflows — Ben, who doesn't want you keeping your existing workflow @@ -69,9 +69,9 @@ practice. In order to provide some motivation, we've collected a number of real, Jujutsu exists) > When I heard about Jujutsu I decided to try it out before forming an opinion. -> Technically it never formed, because I haven't considered going back. +> Technically it never formed, because I haven't considered going back. -— gul banana, computer programmer +— gul banana, computer programmer ## What the developers have to say @@ -94,7 +94,7 @@ Jujutsu exists) — Anton Bulakh, contributor and dopamine enthusiast -> I'm sometimes still surprised that navigating with `jj next` and `jj prev` +> I'm sometimes still surprised that navigating with `jj next` and `jj prev` > works. — Philip Metzger, author of `jj next` and `jj prev` diff --git a/docs/tutorial.md b/docs/tutorial.md index caafab32b6..bfd7f6d52a 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -71,7 +71,7 @@ remove existing files. To untrack a path, add it to your `.gitignore` and run To see the diff, run `jj diff`: ```shell -$ jj diff --git # Feel free to skip the `--git` flag +$ jj diff --git # Feel free to skip the `--git` flag diff --git a/README b/README index 980a0d5f19...1ce3f81130 100644 --- a/README @@ -117,7 +117,7 @@ working copy. Any further changes in the working copy will then amend the commit. Whether you choose to create a new change and squash, or to edit, typically depends on how done you are with the change; if the change is almost done, it makes sense to use `jj new` so you can easily review your adjustments -with `jj diff` before running `jj squash`. +with `jj diff` before running `jj squash`. To view how a change has evolved over time, we can use `jj obslog` to see each recorded change for the current commit. This records changes to the working @@ -151,7 +151,7 @@ to commands that take revisions as arguments. We will generally prefer change IDs because they stay the same when the commit is rewritten. By default, `jj log` lists your local commits, with some remote commits added -for context. The `~` indicates that the commit has parents that are not +for context. The `~` indicates that the commit has parents that are not included in the graph. We can use the `--revisions`/`-r` flag to select a different set of revisions to list. The flag accepts a ["revset"](revsets.md), which is an expression in a simple language for specifying revisions. For @@ -334,18 +334,18 @@ commands to interact with it. To list the operations, use `jj op log`: ```shell $ jj op log -@ d3b77addea49 martinvonz@vonz.svl.corp.google.com 3 minutes ago, lasted 3 milliseconds -│ squash commit 63874fe6c4fba405ffc38b0dd926f03b715cf7ef -│ args: jj squash -◉ 6fc1873c1180 martinvonz@vonz.svl.corp.google.com 3 minutes ago, lasted 1 milliseconds -│ snapshot working copy -│ args: jj squash -◉ ed91f7bcc1fb martinvonz@vonz.svl.corp.google.com 6 minutes ago, lasted 1 milliseconds -│ new empty commit -│ args: jj new puqltutt -◉ 367400773f87 martinvonz@vonz.svl.corp.google.com 12 minutes ago, lasted 3 milliseconds -│ rebase commit daa6ffd5a09a8a7d09a65796194e69b7ed0a566d and descendants -│ args: jj rebase -s puqltutt -d nuvyytnq +@ d3b77addea49 martinvonz@vonz.svl.corp.google.com 3 minutes ago, lasted 3 milliseconds +│ squash commit 63874fe6c4fba405ffc38b0dd926f03b715cf7ef +│ args: jj squash +◉ 6fc1873c1180 martinvonz@vonz.svl.corp.google.com 3 minutes ago, lasted 1 milliseconds +│ snapshot working copy +│ args: jj squash +◉ ed91f7bcc1fb martinvonz@vonz.svl.corp.google.com 6 minutes ago, lasted 1 milliseconds +│ new empty commit +│ args: jj new puqltutt +◉ 367400773f87 martinvonz@vonz.svl.corp.google.com 12 minutes ago, lasted 3 milliseconds +│ rebase commit daa6ffd5a09a8a7d09a65796194e69b7ed0a566d and descendants +│ args: jj rebase -s puqltutt -d nuvyytnq [many more lines] ``` @@ -436,9 +436,10 @@ Now try that: ```shell $ jj squash -i -Using default editor ':builtin'; you can change this by setting ui.diff-editor +Using default editor ':builtin' +you can change this by setting ui.diff-editor Working copy now at: mrxqplyk 52a6c7fd ABCD -Parent commit : kwtuwqnm 643061ac ABC +Parent commit : kwtuwqnm 643061ac ABC ``` That will bring up the built-in diff editor[^alternative_diff_editors] with a @@ -448,12 +449,13 @@ using space. Once complete, press `c` to confirm changes, or `q` to exit without saving. You can also use the mouse to click on the menu items to see more options (keyboard navigation is currently limited). -[^alternative_diff_editors]: There are many other diff editors you could use. -For example, if you have [Meld](https://meldmerge.org) installed and in the -PATH, you can use it via `jj squash -i --tool meld` or a fancier config with `jj +[^alternative_diff_editors]: + There are many other diff editors you could use. + For example, if you have [Meld](https://meldmerge.org) installed and in the + PATH, you can use it via `jj squash -i --tool meld` or a fancier config with `jj squash -i --tool meld-3`. You can configure the default with the -[`ui.diff-editor` option](config.md#editing-diffs); those docs also explain how -to specify a path to an executable if it is not in the PATH. + [`ui.diff-editor` option](config.md#editing-diffs); those docs also explain how + to specify a path to an executable if it is not in the PATH. If we look at the diff of the second commit, we now see that all three lines got capitalized: @@ -461,12 +463,12 @@ that all three lines got capitalized: ```shell $ jj diff -r @- Modified regular file file: - 1 1: aA - 2 2: bB - 3 3: cC +1 1: aA +2 2: bB +3 3: cC ``` -The child change ("ABCD" in our case) will have the same content *state* after +The child change ("ABCD" in our case) will have the same content _state_ after the `jj squash` command. That means that you can move any changes you want into the parent change, even if they touch the same word, and it won't cause any conflicts. diff --git a/docs/windows.md b/docs/windows.md index 5c55c434e7..6e2189e6e5 100644 --- a/docs/windows.md +++ b/docs/windows.md @@ -86,10 +86,10 @@ Then only use the `~/my-repo` workspace from Linux. ## Symbolic link support -`jj` supports symlinks on Windows only when they are enabled by the operating +`jj` supports symlinks on Windows only when they are enabled by the operating system. This requires Windows 10 version 14972 or higher, as well as Developer Mode. If those conditions are not satisfied, `jj` will materialize symlinks as ordinary files. For colocated repositories, Git support must also be enabled using the -`git config` option `core.symlinks=true`. \ No newline at end of file +`git config` option `core.symlinks=true`. diff --git a/docs/working-copy.md b/docs/working-copy.md index 4be1e8a8cc..195ab33b3d 100644 --- a/docs/working-copy.md +++ b/docs/working-copy.md @@ -1,6 +1,5 @@ # Working copy - ## Introduction The working copy is where the current working-copy commit's files are written so @@ -19,7 +18,6 @@ copy, it will implicitly be untracked. To untrack a file while keeping it in the working copy, first make sure it's [ignored](#ignored-files) and then run `jj untrack `. - ## Conflicts When you check out a commit with conflicts, those conflicts need to be @@ -43,13 +41,12 @@ main disadvantage of that is that it's harder to inspect the conflict resolutions. With the `jj resolve` command, you can use an external merge tool to resolve -conflicts that have 2 sides and a base. There is not yet a good way of +conflicts that have 2 sides and a base. There is not yet a good way of resolving conflicts between directories, files, and symlinks (https://github.com/martinvonz/jj/issues/19). You can use `jj restore` to choose one side of the conflict, but there's no way to even see where the involved parts came from. - ## Ignored files You probably don't want build outputs and temporary files to be under version @@ -59,10 +56,9 @@ See https://git-scm.com/docs/gitignore for details about the format. `.gitignore` files are supported in any directory in the working copy, as well as in `$HOME/.gitignore` and `$GIT_DIR/info/exclude`. - ## Workspaces -You can have multiple working copies backed by a single repo. Use +You can have multiple working copies backed by a single repo. Use `jj workspace add` to create a new working copy. The working copy will have a `.jj/` directory linked to the main repo. The working copy and the `.jj/` directory together is called a "workspace". Each workspace can have a different