From af224780aedb7b7f0af95807ac14ced9bf0119e6 Mon Sep 17 00:00:00 2001 From: Christoph Koehler Date: Sun, 31 Mar 2024 19:40:19 -0600 Subject: [PATCH] revset: add working_copies() function It includes the working copy commit of every workspace of the repo. Implements #3384 --- CHANGELOG.md | 2 ++ docs/revsets.md | 2 ++ lib/src/revset.rs | 18 ++++++++++++++++++ lib/tests/test_revset.rs | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8b4e7fa8d..bebfc8b7d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * There is a new global `--quiet` flag to silence commands' non-primary output. +* new function `working_copies()` for revsets to show the working copy commits of all workspaces. + ### Fixed bugs ## [0.15.1] - 2024-03-06 diff --git a/docs/revsets.md b/docs/revsets.md index 2f947c6321..26319bc393 100644 --- a/docs/revsets.md +++ b/docs/revsets.md @@ -171,6 +171,8 @@ given [string pattern](#string-patterns). * `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. + ## String patterns Functions that perform string matching support the following pattern syntax: diff --git a/lib/src/revset.rs b/lib/src/revset.rs index de61b438cc..0e94c27adb 100644 --- a/lib/src/revset.rs +++ b/lib/src/revset.rs @@ -275,6 +275,7 @@ pub const GENERATION_RANGE_EMPTY: Range = 0..0; #[derive(Clone, Debug, Eq, PartialEq)] pub enum RevsetCommitRef { WorkingCopy(WorkspaceId), + WorkingCopies(), Symbol(String), RemoteSymbol { name: String, @@ -371,6 +372,10 @@ impl RevsetExpression { ))) } + pub fn working_copies() -> Rc { + Rc::new(RevsetExpression::CommitRef(RevsetCommitRef::WorkingCopies())) + } + pub fn symbol(value: String) -> Rc { Rc::new(RevsetExpression::CommitRef(RevsetCommitRef::Symbol(value))) } @@ -1157,6 +1162,10 @@ static BUILTIN_FUNCTION_MAP: Lazy> = Lazy: expect_no_arguments(name, arguments_pair)?; Ok(RevsetExpression::all()) }); + map.insert("working_copies", |name, arguments_pair, _state| { + expect_no_arguments(name, arguments_pair)?; + Ok(RevsetExpression::working_copies()) + }); map.insert("heads", |name, arguments_pair, state| { let arg = expect_one_argument(name, arguments_pair)?; let candidates = parse_expression_rule(arg.into_inner(), state)?; @@ -2139,6 +2148,15 @@ fn resolve_commit_ref( }) } } + RevsetCommitRef::WorkingCopies() => { + let wc_commits: Vec = repo + .view() + .wc_commit_ids() + .iter() + .map(|(_, v)| v.clone()) + .collect(); + Ok(wc_commits) + } RevsetCommitRef::VisibleHeads => Ok(repo.view().heads().iter().cloned().collect_vec()), RevsetCommitRef::Root => Ok(vec![repo.store().root_commit_id().clone()]), RevsetCommitRef::Branches(pattern) => { diff --git a/lib/tests/test_revset.rs b/lib/tests/test_revset.rs index ec52420cb1..0934d51265 100644 --- a/lib/tests/test_revset.rs +++ b/lib/tests/test_revset.rs @@ -371,6 +371,39 @@ fn test_resolve_working_copy() { assert_eq!(resolve(ws2), vec![commit2.id().clone()]); } +#[test] +fn test_resolve_working_copies() { + let settings = testutils::user_settings(); + let test_repo = TestRepo::init(); + let repo = &test_repo.repo; + + let mut tx = repo.start_transaction(&settings); + let mut_repo = tx.mut_repo(); + + let commit1 = write_random_commit(mut_repo, &settings); + let commit2 = write_random_commit(mut_repo, &settings); + + let ws1 = WorkspaceId::new("ws1".to_string()); + let ws2 = WorkspaceId::new("ws2".to_string()); + + // Add some workspaces + mut_repo + .set_wc_commit(ws1.clone(), commit1.id().clone()) + .unwrap(); + mut_repo + .set_wc_commit(ws2.clone(), commit2.id().clone()) + .unwrap(); + let resolve = || -> Vec { + RevsetExpression::working_copies() + .evaluate_programmatic(mut_repo) + .unwrap() + .iter() + .collect() + }; + + assert_eq!(resolve(), vec![commit2.id().clone(), commit1.id().clone()]); +} + #[test] fn test_resolve_symbol_branches() { let settings = testutils::user_settings();