From 70dc5fedbe3304e6c3ca528644d7f8148cfda69c Mon Sep 17 00:00:00 2001 From: Matt Stark Date: Wed, 5 Jun 2024 09:34:50 +1000 Subject: [PATCH 1/2] chore: Make squash tests log empty commits. --- cli/tests/test_squash_command.rs | 70 +++++++++++++++++--------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/cli/tests/test_squash_command.rs b/cli/tests/test_squash_command.rs index b3f8d1ed41..efa9174cd0 100644 --- a/cli/tests/test_squash_command.rs +++ b/cli/tests/test_squash_command.rs @@ -35,7 +35,7 @@ fn test_squash() { @ 382c9bad7d42 c ◉ d5d59175b481 b ◉ 184ddbcce5a9 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // Squashes the working copy into the parent by default @@ -46,10 +46,10 @@ fn test_squash() { Parent commit : kkmpptxz 59f44460 b c | (no description set) "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ f7bb78d8da62 + @ f7bb78d8da62 (empty) ◉ 59f4446070a0 b c ◉ 184ddbcce5a9 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1"]); insta::assert_snapshot!(stdout, @r###" @@ -68,7 +68,7 @@ fn test_squash() { insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @ 1d70f50afa6d c ◉ 9146bcc8d996 a b - ◉ 000000000000 + ◉ 000000000000 (empty) "###); let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1", "-r", "b"]); insta::assert_snapshot!(stdout, @r###" @@ -89,14 +89,14 @@ fn test_squash() { test_env.jj_cmd_ok(&repo_path, &["new", "c", "d"]); test_env.jj_cmd_ok(&repo_path, &["branch", "create", "e"]); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 41219719ab5f e + @ 41219719ab5f e (empty) ├─╮ │ ◉ f86e2b3af3e3 d ◉ │ 382c9bad7d42 c ├─╯ ◉ d5d59175b481 b ◉ 184ddbcce5a9 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); let stderr = test_env.jj_cmd_failure(&repo_path, &["squash"]); insta::assert_snapshot!(stderr, @r###" @@ -113,7 +113,7 @@ fn test_squash() { Parent commit : nmzmmopx 338cbc05 e | (no description set) "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ b50b843d8555 + @ b50b843d8555 (empty) ◉ 338cbc05e4e6 e ├─╮ │ ◉ f86e2b3af3e3 d @@ -121,7 +121,7 @@ fn test_squash() { ├─╯ ◉ d5d59175b481 b ◉ 184ddbcce5a9 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1", "-r", "e"]); insta::assert_snapshot!(stdout, @r###" @@ -151,7 +151,7 @@ fn test_squash_partial() { @ a0b1a272ebc4 c ◉ d117da276a0f b ◉ 54d3c1c0e9fd a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // If we don't make any changes in the diff-editor, the whole change is moved @@ -167,7 +167,7 @@ fn test_squash_partial() { insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @ 3c6332267ea8 c ◉ 38ffd8b98578 a b - ◉ 000000000000 + ◉ 000000000000 (empty) "###); let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1", "-r", "a"]); insta::assert_snapshot!(stdout, @r###" @@ -188,7 +188,7 @@ fn test_squash_partial() { @ 57c3cf20d0b1 c ◉ c4925e01d298 b ◉ 1fc159063ed3 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1", "-r", "a"]); insta::assert_snapshot!(stdout, @r###" @@ -222,7 +222,7 @@ fn test_squash_partial() { @ 64d7ad7c43c1 c ◉ 60a264527aee b ◉ 7314692d32e3 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1", "-r", "a"]); insta::assert_snapshot!(stdout, @r###" @@ -305,7 +305,7 @@ fn test_squash_from_to() { │ ◉ 12d6103dc0c8 b ├─╯ ◉ b7b767179c44 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // Errors out if source and destination are the same @@ -329,7 +329,7 @@ fn test_squash_from_to() { │ ◉ 12d6103dc0c8 b c ├─╯ ◉ b7b767179c44 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // The change from the source has been applied let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1"]); @@ -359,7 +359,7 @@ fn test_squash_from_to() { │ ◉ 12d6103dc0c8 b ├─╯ ◉ b7b767179c44 a d - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // The change from the source has been applied (the file contents were already // "f", as is typically the case when moving changes from an ancestor) @@ -387,7 +387,7 @@ fn test_squash_from_to() { │ ◉ 12d6103dc0c8 b ├─╯ ◉ b7b767179c44 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // The change from the source has been applied let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file2", "-r", "d"]); @@ -430,7 +430,7 @@ fn test_squash_from_to_partial() { │ ◉ 12d6103dc0c8 b ├─╯ ◉ b7b767179c44 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); let edit_script = test_env.set_up_fake_diff_editor(); @@ -448,7 +448,7 @@ fn test_squash_from_to_partial() { │ ◉ 12d6103dc0c8 b c ├─╯ ◉ b7b767179c44 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // The changes from the source has been applied let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1"]); @@ -481,7 +481,7 @@ fn test_squash_from_to_partial() { │ ◉ 12d6103dc0c8 b ├─╯ ◉ b7b767179c44 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // The selected change from the source has been applied let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1"]); @@ -516,7 +516,7 @@ fn test_squash_from_to_partial() { │ ◉ 12d6103dc0c8 b ├─╯ ◉ b7b767179c44 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // The selected change from the source has been applied let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1"]); @@ -552,7 +552,7 @@ fn test_squash_from_to_partial() { │ @ e0dac715116f d ├─╯ ◉ b7b767179c44 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // The selected change from the source has been applied let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1", "-r", "b"]); @@ -618,7 +618,7 @@ fn test_squash_from_multiple() { ◉ │ aaf7b53a1b64 d ├─╯ ◉ 3b1673b6370c a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // Squash a few commits sideways @@ -644,7 +644,7 @@ fn test_squash_from_multiple() { ◉ │ 98759debcee5 d ├─╯ ◉ 3b1673b6370c a b c - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // The changes from the sources have been applied let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "-r=d", "file"]); @@ -671,13 +671,13 @@ fn test_squash_from_multiple() { Parent commit : yostqsxw c1293ff7 e f | (no description set) "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 6a670d1ac76e + @ 6a670d1ac76e (empty) ◉ c1293ff7be51 e f ├─╮ ◉ │ aaf7b53a1b64 d ├─╯ ◉ 3b1673b6370c a b c - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // The changes from the sources have been applied to the destination let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "-r=e", "file"]); @@ -743,7 +743,7 @@ fn test_squash_from_multiple_partial() { ◉ │ 763809ca0131 d ├─╯ ◉ 54d3c1c0e9fd a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // Partially squash a few commits sideways @@ -772,7 +772,7 @@ fn test_squash_from_multiple_partial() { ◉ │ b91b11575906 d ├─╯ ◉ 54d3c1c0e9fd a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // The selected changes have been removed from the sources let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "-r=b", "file1"]); @@ -824,7 +824,7 @@ fn test_squash_from_multiple_partial() { ◉ │ 763809ca0131 d ├─╯ ◉ 54d3c1c0e9fd a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // The selected changes have been removed from the sources let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "-r=b", "file1"]); @@ -881,7 +881,7 @@ fn test_squash_from_multiple_partial_no_op() { │ ◉ b73077b08c59 b ├─╯ ◉ 2443ea76b0b1 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); // Source commits that didn't match the paths are not rewritten @@ -900,7 +900,7 @@ fn test_squash_from_multiple_partial_no_op() { │ ◉ f40b442af3e8 c ├─╯ ◉ 2443ea76b0b1 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); let stdout = test_env.jj_cmd_success( &repo_path, @@ -936,12 +936,18 @@ fn test_squash_from_multiple_partial_no_op() { │ ◉ b73077b08c59 b ├─╯ ◉ 2443ea76b0b1 a - ◉ 000000000000 + ◉ 000000000000 (empty) "###); } fn get_log_output(test_env: &TestEnvironment, repo_path: &Path) -> String { - let template = r#"separate(" ", commit_id.short(), branches, description)"#; + let template = r#"separate( + " ", + commit_id.short(), + branches, + description, + if(empty, "(empty)") + )"#; test_env.jj_cmd_success(repo_path, &["log", "-T", template]) } From 71d9c218d2d09cda0d041780d92564404a4592ad Mon Sep 17 00:00:00 2001 From: Matt Stark Date: Wed, 5 Jun 2024 09:34:50 +1000 Subject: [PATCH 2/2] feat(squash): Add `--keep-emptied` flag Fixes #3815 --- CHANGELOG.md | 159 +++++++++++++++++-------------- cli/src/commands/move.rs | 1 + cli/src/commands/squash.rs | 11 ++- cli/tests/cli-reference@.md.snap | 3 +- cli/tests/test_squash_command.rs | 43 +++++++++ 5 files changed, 141 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f12d377feb..9cc374473a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +and this project adheres +to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] @@ -134,7 +135,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * 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. @@ -162,6 +164,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `jj git push` now can push commits with empty descriptions with the `--allow-empty-description` flag +* `jj squash` now accepts a `--keep-emptied` option to keep the source commit. + ### Fixed bugs * Previously, `jj git push` only made sure that the branch is in the expected @@ -176,12 +180,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 fetch` works, `jj` does not suffer from the same problems as Git's `git push --force-with-lease` in situations when `git fetch` is run in the background. -* When the working copy commit becomes immutable, a new one is automatically created +* 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). -* 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. * The progress bar (visible when using e.g. `jj git clone`) clears the @@ -220,7 +225,8 @@ Thanks to the people who made this release happen! ### 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 @@ -279,7 +285,7 @@ Thanks to the people who made this release happen! `jj debug watchman status` command. * `jj rebase` now accepts revsets resolving to multiple revisions with the - `--revisions`/`-r` option. + `--revisions`/`-r` option. * `jj rebase -r` now accepts `--insert-after` and `--insert-before` options to customize the location of the rebased revisions. @@ -327,7 +333,6 @@ Thanks to the people who made this release happen! * Théo Daron (@tdaron) * Yuya Nishihara (@yuja) - ## [0.16.0] - 2024-04-03 ### Deprecations @@ -345,11 +350,13 @@ Thanks to the people who made this release happen! * 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 default `jj` commands. @@ -375,7 +382,8 @@ Thanks to the people who made this release happen! * `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, for consistency with other commands. @@ -389,7 +397,8 @@ Thanks to the people who made this release happen! * `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 @@ -421,7 +430,6 @@ Thanks to the people who made this release happen! * TrashCan (@TrashCan69420) * Yuya Nishihara (@yuja) - ## [0.15.1] - 2024-03-06 No code changes (fixing Rust `Cargo.toml` stuff). @@ -496,15 +504,17 @@ No code changes (fixing Rust `Cargo.toml` stuff). * `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 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` @@ -520,8 +530,10 @@ No code changes (fixing Rust `Cargo.toml` stuff). ### Fixed bugs -* 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 +* 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) @@ -558,7 +570,6 @@ Thanks to the people who made this release happen! * Vladimir (@0xdeafbeef) * Yuya Nishihara (@yuja) - ## [0.14.0] - 2024-02-07 ### Deprecations @@ -587,12 +598,12 @@ 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 @@ -620,7 +631,8 @@ Thanks to the people who made this release happen! * `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. @@ -684,7 +696,6 @@ Thanks to the people who made this release happen! * vwkd (@vwkd) * Yuya Nishihara (@yuja) - ## [0.13.0] - 2024-01-03 ### Breaking changes @@ -718,7 +729,6 @@ Thanks to the people who made this release happen! * Waleed Khan (@arxanas) * Yuya Nishihara (@yuja) - ## [0.12.0] - 2023-12-05 ### Breaking changes @@ -779,7 +789,6 @@ Thanks to the people who made this release happen! * Waleed Khan (@arxanas) * Yuya Nishihara (@yuja) - ## [0.11.0] - 2023-11-01 ### Breaking changes @@ -827,7 +836,8 @@ Thanks to the people who made this release happen! ### 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. @@ -880,14 +890,15 @@ Thanks to the people who made this release happen! * 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) + Check [revsets.toml](cli/src/config/revsets.toml) + and [revsets.md](docs/revsets.md) to understand how the function can be adapted. ### New features @@ -943,7 +954,6 @@ Thanks to the people who made this release happen! * Yuya Nishihara (@yuja) * Zachary Dremann (@Dr-Emann) - ## [0.9.0] - 2023-09-06 ### Breaking changes @@ -968,7 +978,8 @@ Thanks to the people who made this release happen! * 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 @@ -1010,7 +1021,8 @@ Thanks to the people who made this release happen! * `jj init --git-repo` now works with bare repositories. * `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. + config location if no existing file is found, potentially creating parent + directories. * `jj log` output is now topologically grouped. [#242](https://github.com/martinvonz/jj/issues/242) @@ -1051,7 +1063,8 @@ Thanks to the people who made this release happen! 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 operands omitted. These expressions are equivalent to `all()` and `~root()` @@ -1059,7 +1072,8 @@ Thanks to the people who made this release happen! * `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 @@ -1068,7 +1082,8 @@ Thanks to the people who made this release happen! further pending improvements. * `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) + 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 instead of just the default remote @@ -1078,7 +1093,8 @@ Thanks to the people who made this release happen! * 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 [#1970](https://github.com/martinvonz/jj/issues/1970) @@ -1120,7 +1136,6 @@ Thanks to the people who made this release happen! * Yuya Nishihara (@yuja) * Zachary Dremann (@Dr-Emann) - ## [0.8.0] - 2023-07-09 ### Breaking changes @@ -1165,7 +1180,8 @@ Thanks to the people who made this release happen! ### 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 commit. @@ -1321,7 +1337,6 @@ Thanks to the people who made this release happen! * Waleed Khan (@arxanas) * Yuya Nishihara (@yuja) - ## [0.7.0] - 2023-02-16 ### Breaking changes @@ -1505,7 +1520,8 @@ Thanks to the people who made this release happen! * `jj undo` now works after `jj duplicate`. * `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 + 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. @@ -1517,25 +1533,25 @@ Thanks to the people who made this release happen! 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 @@ -1660,17 +1676,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 @@ -1935,9 +1950,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/cli/src/commands/move.rs b/cli/src/commands/move.rs index 1bcea4670e..230c722a45 100644 --- a/cli/src/commands/move.rs +++ b/cli/src/commands/move.rs @@ -100,6 +100,7 @@ pub(crate) fn cmd_move( SquashedDescription::Combine, false, &args.paths, + false, )?; tx.finish(ui, tx_description)?; Ok(()) diff --git a/cli/src/commands/squash.rs b/cli/src/commands/squash.rs index 58290fb8ff..c325a584d5 100644 --- a/cli/src/commands/squash.rs +++ b/cli/src/commands/squash.rs @@ -38,8 +38,8 @@ use crate::ui::Ui; /// commit to the grandparent. /// /// If, after moving changes out, the source revision is empty compared to its -/// parent(s), it will be abandoned. Without `--interactive`, the source -/// revision will always be empty. +/// parent(s), and `--keep-emptied` is not set, it will be abandoned. Without +/// `--interactive` or paths, the source revision will always be empty. /// /// If the source became empty and both the source and destination had a /// non-empty description, you will be asked for the combined description. If @@ -74,6 +74,9 @@ pub(crate) struct SquashArgs { /// Move only changes to these paths (instead of all paths) #[arg(conflicts_with_all = ["interactive", "tool"], value_hint = clap::ValueHint::AnyPath)] paths: Vec, + /// The source revision will not be abandoned + #[arg(long)] + keep_emptied: bool, } #[instrument(skip_all)] @@ -132,6 +135,7 @@ pub(crate) fn cmd_squash( SquashedDescription::from_args(args), args.revision.is_none() && args.from.is_empty() && args.into.is_none(), &args.paths, + args.keep_emptied, )?; tx.finish(ui, tx_description)?; Ok(()) @@ -177,6 +181,7 @@ pub fn move_diff( description: SquashedDescription, no_rev_arg: bool, path_arg: &[String], + keep_emptied: bool, ) -> Result<(), CommandError> { tx.base_workspace_helper() .check_rewritable(sources.iter().chain(std::iter::once(destination)).ids())?; @@ -210,7 +215,7 @@ from the source will be moved into the destination. let selected_tree_id = diff_selector.select(&parent_tree, &source_tree, matcher, Some(&instructions))?; let selected_tree = tx.repo().store().get_root_tree(&selected_tree_id)?; - let abandon = selected_tree.id() == source_tree.id(); + let abandon = !keep_emptied && selected_tree.id() == source_tree.id(); if !abandon && selected_tree_id == parent_tree.id() { // Nothing selected from this commit. If it's abandoned (i.e. already empty), we // still include it so `jj squash` can be used for abandoning an empty commit in diff --git a/cli/tests/cli-reference@.md.snap b/cli/tests/cli-reference@.md.snap index a473a5c5f6..6d23499cc5 100644 --- a/cli/tests/cli-reference@.md.snap +++ b/cli/tests/cli-reference@.md.snap @@ -1732,7 +1732,7 @@ With the `-r` option, moves the changes from the specified revision to the paren With the `--from` and/or `--into` options, moves changes from/to the given revisions. If either is left out, it defaults to the working-copy commit. For example, `jj squash --into @--` moves changes from the working-copy commit to the grandparent. -If, after moving changes out, the source revision is empty compared to its parent(s), it will be abandoned. Without `--interactive`, the source revision will always be empty. +If, after moving changes out, the source revision is empty compared to its parent(s), and `--keep-emptied` is not set, it will be abandoned. Without `--interactive` or paths, the source revision will always be empty. If the source became empty and both the source and destination had a non-empty description, you will be asked for the combined description. If either was empty, then the other one will be used. @@ -1753,6 +1753,7 @@ If a working-copy commit gets abandoned, it will be given a new, empty commit. T * `-u`, `--use-destination-message` — Use the description of the destination revision and discard the description(s) of the source revision(s) * `-i`, `--interactive` — Interactively choose which parts to squash * `--tool ` — Specify diff editor to be used (implies --interactive) +* `--keep-emptied` — The source revision will not be abandoned diff --git a/cli/tests/test_squash_command.rs b/cli/tests/test_squash_command.rs index efa9174cd0..b1d3ad7900 100644 --- a/cli/tests/test_squash_command.rs +++ b/cli/tests/test_squash_command.rs @@ -259,6 +259,49 @@ fn test_squash_partial() { insta::assert_snapshot!(stdout, @""); } +#[test] +fn test_squash_keep_emptied() { + let test_env = TestEnvironment::default(); + test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]); + let repo_path = test_env.env_root().join("repo"); + + test_env.jj_cmd_ok(&repo_path, &["branch", "create", "a"]); + std::fs::write(repo_path.join("file1"), "a\n").unwrap(); + test_env.jj_cmd_ok(&repo_path, &["new"]); + test_env.jj_cmd_ok(&repo_path, &["branch", "create", "b"]); + std::fs::write(repo_path.join("file1"), "b\n").unwrap(); + test_env.jj_cmd_ok(&repo_path, &["new"]); + test_env.jj_cmd_ok(&repo_path, &["branch", "create", "c"]); + std::fs::write(repo_path.join("file1"), "c\n").unwrap(); + // Test the setup + + insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" + @ 382c9bad7d42 c + ◉ d5d59175b481 b + ◉ 184ddbcce5a9 a + ◉ 000000000000 (empty) + "###); + + let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["squash", "-r", "b", "--keep-emptied"]); + insta::assert_snapshot!(stdout, @""); + insta::assert_snapshot!(stderr, @r###" + Rebased 2 descendant commits + Working copy now at: mzvwutvl 7ee7f18a c | (no description set) + Parent commit : kkmpptxz 9490bd7f b | (empty) (no description set) + "###); + // With --keep-emptied, b remains even though it is now empty. + insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" + @ 7ee7f18a5223 c + ◉ 9490bd7f1e6a b (empty) + ◉ 53bf93080518 a + ◉ 000000000000 (empty) + "###); + let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1", "-r", "a"]); + insta::assert_snapshot!(stdout, @r###" + b + "###); +} + #[test] fn test_squash_from_to() { let test_env = TestEnvironment::default();