From db226d9f64773e000d0164a8471b1c012b4e8c89 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Tue, 1 Oct 2024 12:29:25 +0900 Subject: [PATCH] revset: fix crash on "log --at-op 00000000 -r 'root()'" Spotted while refactoring IdPrefixContext. --- lib/src/revset.rs | 13 ++++++++++++- lib/tests/test_revset.rs | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/src/revset.rs b/lib/src/revset.rs index 927d423348..89a3179596 100644 --- a/lib/src/revset.rs +++ b/lib/src/revset.rs @@ -1798,7 +1798,18 @@ fn resolve_commit_ref( Ok(wc_commits) } RevsetCommitRef::VisibleHeads => Ok(repo.view().heads().iter().cloned().collect_vec()), - RevsetCommitRef::Root => Ok(vec![repo.store().root_commit_id().clone()]), + RevsetCommitRef::Root => { + let commit_id = repo.store().root_commit_id(); + if repo.index().has_id(commit_id) { + Ok(vec![commit_id.clone()]) + } else { + // The root commit doesn't exist at the root operation. + Err(RevsetResolutionError::NoSuchRevision { + name: "root()".to_owned(), + candidates: vec![], + }) + } + } RevsetCommitRef::Bookmarks(pattern) => { let commit_ids = repo .view() diff --git a/lib/tests/test_revset.rs b/lib/tests/test_revset.rs index 4dc99b08aa..3034c1293c 100644 --- a/lib/tests/test_revset.rs +++ b/lib/tests/test_revset.rs @@ -34,6 +34,7 @@ use jj_lib::op_store::RefTarget; use jj_lib::op_store::RemoteRef; use jj_lib::op_store::RemoteRefState; use jj_lib::op_store::WorkspaceId; +use jj_lib::operation::Operation; use jj_lib::repo::Repo; use jj_lib::repo_path::RepoPath; use jj_lib::repo_path::RepoPathUiConverter; @@ -942,6 +943,14 @@ fn test_evaluate_expression_root_and_checkout() { let test_workspace = TestWorkspace::init(&settings); let repo = &test_workspace.repo; + let root_operation = { + let op_store = repo.op_store(); + let id = op_store.root_operation_id(); + let data = op_store.read_operation(id).unwrap(); + Operation::new(op_store.clone(), id.clone(), data) + }; + let root_repo = repo.reload_at(&root_operation).unwrap(); + let mut tx = repo.start_transaction(&settings); let mut_repo = tx.repo_mut(); @@ -954,6 +963,14 @@ fn test_evaluate_expression_root_and_checkout() { vec![root_commit.id().clone()] ); + // but not in the root operation. It might be okay to pretend that the root + // commit exists in the root operation, but queries like "root()" shouldn't + // panic in any case. + assert_matches!( + resolve_symbol(root_repo.as_ref(), "root()"), + Err(RevsetResolutionError::NoSuchRevision { .. }) + ); + // Can find the current working-copy commit mut_repo .set_wc_commit(WorkspaceId::default(), commit1.id().clone())