cli: simplify-parents: add default revsets.simplify-parents config
Some checks are pending
binaries / Build binary artifacts (push) Waiting to run
nix / flake check (push) Waiting to run
build / build (, macos-13) (push) Waiting to run
build / build (, macos-14) (push) Waiting to run
build / build (, ubuntu-latest) (push) Waiting to run
build / build (, windows-latest) (push) Waiting to run
build / build (--all-features, ubuntu-latest) (push) Waiting to run
build / Build jj-lib without Git support (push) Waiting to run
build / Check protos (push) Waiting to run
build / Check formatting (push) Waiting to run
build / Check that MkDocs can build the docs (push) Waiting to run
build / Check that MkDocs can build the docs with latest Python and uv (push) Waiting to run
build / cargo-deny (advisories) (push) Waiting to run
build / cargo-deny (bans licenses sources) (push) Waiting to run
build / Clippy check (push) Waiting to run
Codespell / Codespell (push) Waiting to run
website / prerelease-docs-build-deploy (ubuntu-latest) (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run

This adds a new `revsets.simplify-parents` configuration option (similar
to `revsets.fix`) which serves as the default revset for `jj
simplify-parents` if no `--source` or `--revisions` arguments are
provided.
This commit is contained in:
Benjamin Tan 2024-11-16 01:57:30 +08:00
parent f6210aa99d
commit ee37409c5e
6 changed files with 109 additions and 38 deletions

View file

@ -71,6 +71,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
"diff3" conflict style, meaning it is more likely to work with external tools, "diff3" conflict style, meaning it is more likely to work with external tools,
but it doesn't support conflicts with more than 2 sides. but it doesn't support conflicts with more than 2 sides.
* `jj simplify-parents` now supports configuring the default revset when no
`--source` or `--revisions` arguments are provided with the
`revsets.simplify-parents` config.
### Fixed bugs ### Fixed bugs
* `jj config unset <TABLE-NAME>` no longer removes a table (such as `[ui]`.) * `jj config unset <TABLE-NAME>` no longer removes a table (such as `[ui]`.)

View file

@ -20,22 +20,17 @@ use crate::ui::Ui;
/// ancestor of B, A will be rewritten to have only B as a parent instead of /// ancestor of B, A will be rewritten to have only B as a parent instead of
/// B+C. /// B+C.
#[derive(clap::Args, Clone, Debug)] #[derive(clap::Args, Clone, Debug)]
#[command(group = clap::ArgGroup::new("revision-args").multiple(true).required(true))]
pub(crate) struct SimplifyParentsArgs { pub(crate) struct SimplifyParentsArgs {
/// Simplify specified revision(s) together with their trees of descendants /// Simplify specified revision(s) together with their trees of descendants
/// (can be repeated) /// (can be repeated)
#[arg( #[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))]
long, short,
group = "revision-args",
add = ArgValueCandidates::new(complete::mutable_revisions),
)]
source: Vec<RevisionArg>, source: Vec<RevisionArg>,
/// Simplify specified revision(s) (can be repeated) /// Simplify specified revision(s) (can be repeated)
#[arg( ///
long, short, /// If both `--source` and `--revisions` are not provided, this defaults to
group = "revision-args", /// the `revsets.simplify-parents` setting, or `reachable(@, mutable())`
add = ArgValueCandidates::new(complete::mutable_revisions), /// if it is not set.
)] #[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))]
revisions: Vec<RevisionArg>, revisions: Vec<RevisionArg>,
} }
@ -45,16 +40,24 @@ pub(crate) fn cmd_simplify_parents(
args: &SimplifyParentsArgs, args: &SimplifyParentsArgs,
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?; let mut workspace_command = command.workspace_helper(ui)?;
let revs = RevsetExpression::descendants( let revs = if args.source.is_empty() && args.revisions.is_empty() {
let revs = command.settings().get_string("revsets.simplify-parents")?;
workspace_command workspace_command
.parse_union_revsets(ui, &args.source)? .parse_revset(ui, &RevisionArg::from(revs))?
.expression(), .expression()
) .clone()
.union( } else {
workspace_command RevsetExpression::descendants(
.parse_union_revsets(ui, &args.revisions)? workspace_command
.expression(), .parse_union_revsets(ui, &args.source)?
); .expression(),
)
.union(
workspace_command
.parse_union_revsets(ui, &args.revisions)?
.expression(),
)
};
let commit_ids: Vec<_> = workspace_command let commit_ids: Vec<_> = workspace_command
.attach_revset_evaluator(revs) .attach_revset_evaluator(revs)
.evaluate_to_commit_ids()? .evaluate_to_commit_ids()?

View file

@ -421,6 +421,11 @@
"type": "string", "type": "string",
"description": "Revisions to give shorter change and commit IDs to", "description": "Revisions to give shorter change and commit IDs to",
"default": "<revsets.log>" "default": "<revsets.log>"
},
"simplify-parents": {
"type": "string",
"description": "Default set of revisions to simplify when no explicit revset is given for jj simplify-parents",
"default": "reachable(@, mutable())"
} }
}, },
"additionalProperties": { "additionalProperties": {

View file

@ -3,6 +3,7 @@
[revsets] [revsets]
fix = "reachable(@, mutable())" fix = "reachable(@, mutable())"
simplify-parents = "reachable(@, mutable())"
# log revset is also used as the default short-prefixes. If it failed to # log revset is also used as the default short-prefixes. If it failed to
# evaluate, lengthy warning messages would be printed. Use present(expr) to # evaluate, lengthy warning messages would be printed. Use present(expr) to
# suppress symbol resolution error. # suppress symbol resolution error.
@ -13,8 +14,8 @@ log = "present(@) | ancestors(immutable_heads().., 2) | present(trunk())"
# symbol resolution error should be suppressed. # symbol resolution error should be suppressed.
'trunk()' = ''' 'trunk()' = '''
latest( latest(
remote_bookmarks(exact:"main", exact:"origin") | remote_bookmarks(exact:"main", exact:"origin") |
remote_bookmarks(exact:"master", exact:"origin") | remote_bookmarks(exact:"master", exact:"origin") |
remote_bookmarks(exact:"trunk", exact:"origin") | remote_bookmarks(exact:"trunk", exact:"origin") |
remote_bookmarks(exact:"main", exact:"upstream") | remote_bookmarks(exact:"main", exact:"upstream") |
remote_bookmarks(exact:"master", exact:"upstream") | remote_bookmarks(exact:"master", exact:"upstream") |

View file

@ -1975,13 +1975,15 @@ Removes all parents of each of the specified revisions that are also indirect an
In other words, for all (A, B, C) where A has (B, C) as parents and C is an ancestor of B, A will be rewritten to have only B as a parent instead of B+C. In other words, for all (A, B, C) where A has (B, C) as parents and C is an ancestor of B, A will be rewritten to have only B as a parent instead of B+C.
**Usage:** `jj simplify-parents <--source <SOURCE>|--revisions <REVISIONS>>` **Usage:** `jj simplify-parents [OPTIONS]`
###### **Options:** ###### **Options:**
* `-s`, `--source <SOURCE>` — Simplify specified revision(s) together with their trees of descendants (can be repeated) * `-s`, `--source <SOURCE>` — Simplify specified revision(s) together with their trees of descendants (can be repeated)
* `-r`, `--revisions <REVISIONS>` — Simplify specified revision(s) (can be repeated) * `-r`, `--revisions <REVISIONS>` — Simplify specified revision(s) (can be repeated)
If both `--source` and `--revisions` are not provided, this defaults to the `revsets.simplify-parents` setting, or `reachable(@, mutable())` if it is not set.
## `jj sparse` ## `jj sparse`

View file

@ -36,21 +36,6 @@ fn create_commit(test_env: &TestEnvironment, repo_path: &Path, name: &str, paren
test_env.jj_cmd_ok(repo_path, &["bookmark", "create", name]); test_env.jj_cmd_ok(repo_path, &["bookmark", "create", name]);
} }
#[test]
fn test_simplify_parents_no_args() {
let (test_env, repo_path) = create_repo();
let stderr = test_env.jj_cmd_cli_error(&repo_path, &["simplify-parents"]);
insta::assert_snapshot!(stderr, @r###"
error: the following required arguments were not provided:
<--source <SOURCE>|--revisions <REVISIONS>>
Usage: jj simplify-parents <--source <SOURCE>|--revisions <REVISIONS>>
For more information, try '--help'.
"###);
}
#[test] #[test]
fn test_simplify_parents_no_commits() { fn test_simplify_parents_no_commits() {
let (test_env, repo_path) = create_repo(); let (test_env, repo_path) = create_repo();
@ -248,3 +233,74 @@ fn test_simplify_parents_multiple_redundant_parents() {
"#); "#);
} }
#[test]
fn test_simplify_parents_no_args() {
let (test_env, repo_path) = create_repo();
create_commit(&test_env, &repo_path, "a", &["root()"]);
create_commit(&test_env, &repo_path, "b", &["a"]);
create_commit(&test_env, &repo_path, "c", &["a", "b"]);
create_commit(&test_env, &repo_path, "d", &["c"]);
create_commit(&test_env, &repo_path, "e", &["d"]);
create_commit(&test_env, &repo_path, "f", &["d", "e"]);
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "all()", "-T", "description"]);
insta::assert_snapshot!(stdout, @r#"
@ f
e
d
c
b
a
"#);
let setup_opid = test_env.current_operation_id(&repo_path);
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["simplify-parents"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r#"
Removed 2 edges from 2 out of 6 commits.
Rebased 2 descendant commits
Working copy now at: kmkuslsw 8cc01e1b f | f
Parent commit : znkkpsqq 040ae3a6 e | e
"#);
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "all()", "-T", "description"]);
insta::assert_snapshot!(stdout, @r#"
@ f
e
d
c
b
a
"#);
// Test with custom `revsets.simplify-parents`.
test_env.jj_cmd_ok(&repo_path, &["op", "restore", &setup_opid]);
test_env.add_config(r#"revsets.simplify-parents = "d::""#);
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["simplify-parents"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r#"
Removed 1 edges from 1 out of 3 commits.
Working copy now at: kmkuslsw 0c6b4c43 f | f
Parent commit : znkkpsqq 6a679611 e | e
"#);
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "all()", "-T", "description"]);
insta::assert_snapshot!(stdout, @r#"
@ f
e
d
c
b
a
"#);
}