mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-12 15:16:35 +00:00
revsets: add revset function for getting all git refs
This adds a `git_refs()` revset that includes all commits pointed to by a git ref. It's not very useful yet because the graph log doesn't use the right type of edges for non-contiguous commits.
This commit is contained in:
parent
f5151bdbbe
commit
46edbbef09
2 changed files with 59 additions and 2 deletions
|
@ -119,6 +119,7 @@ pub enum RevsetExpression {
|
|||
},
|
||||
AllHeads,
|
||||
PublicHeads,
|
||||
GitRefs,
|
||||
NonObsoleteHeads(Rc<RevsetExpression>),
|
||||
Description {
|
||||
needle: String,
|
||||
|
@ -410,6 +411,16 @@ fn parse_function_expression(
|
|||
})
|
||||
}
|
||||
}
|
||||
"git_refs" => {
|
||||
if arg_count == 0 {
|
||||
Ok(RevsetExpression::GitRefs)
|
||||
} else {
|
||||
Err(RevsetParseError::InvalidFunctionArguments {
|
||||
name,
|
||||
message: "Expected 0 arguments".to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
"description" => {
|
||||
if !(1..=2).contains(&arg_count) {
|
||||
return Err(RevsetParseError::InvalidFunctionArguments {
|
||||
|
@ -726,7 +737,7 @@ pub fn evaluate_expression<'revset, 'repo: 'revset>(
|
|||
let mut parent_entries: Vec<_> =
|
||||
base_set.iter().flat_map(|entry| entry.parents()).collect();
|
||||
parent_entries.sort_by_key(|b| Reverse(b.position()));
|
||||
parent_entries.dedup_by_key(|entry| entry.position());
|
||||
parent_entries.dedup();
|
||||
Ok(Box::new(EagerRevset {
|
||||
index_entries: parent_entries,
|
||||
}))
|
||||
|
@ -802,6 +813,18 @@ pub fn evaluate_expression<'revset, 'repo: 'revset>(
|
|||
index_entries.sort_by_key(|b| Reverse(b.position()));
|
||||
Ok(Box::new(EagerRevset { index_entries }))
|
||||
}
|
||||
RevsetExpression::GitRefs => {
|
||||
let index = repo.index();
|
||||
let mut index_entries: Vec<_> = repo
|
||||
.view()
|
||||
.git_refs()
|
||||
.values()
|
||||
.map(|id| index.entry_by_id(id).unwrap())
|
||||
.collect();
|
||||
index_entries.sort_by_key(|b| Reverse(b.position()));
|
||||
index_entries.dedup();
|
||||
Ok(Box::new(EagerRevset { index_entries }))
|
||||
}
|
||||
RevsetExpression::Description {
|
||||
needle,
|
||||
candidates: base_expression,
|
||||
|
@ -870,7 +893,6 @@ fn non_obsolete_heads<'revset, 'repo: 'revset>(
|
|||
.map(|id| index.entry_by_id(id).unwrap())
|
||||
.collect();
|
||||
index_entries.sort_by_key(|b| Reverse(b.position()));
|
||||
index_entries.sort_by_key(|b| Reverse(b.position()));
|
||||
Box::new(EagerRevset { index_entries })
|
||||
}
|
||||
|
||||
|
|
|
@ -714,6 +714,41 @@ fn test_evaluate_expression_public_heads(use_git: bool) {
|
|||
tx.discard();
|
||||
}
|
||||
|
||||
#[test_case(false ; "local store")]
|
||||
#[test_case(true ; "git store")]
|
||||
fn test_evaluate_expression_git_refs(use_git: bool) {
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
||||
let commit1 = testutils::create_random_commit(&settings, &repo).write_to_repo(mut_repo);
|
||||
let commit2 = testutils::create_random_commit(&settings, &repo).write_to_repo(mut_repo);
|
||||
|
||||
// Can get git refs when there are none
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo.as_repo_ref(), "git_refs()"),
|
||||
vec![]
|
||||
);
|
||||
// Can get a mix of git refs
|
||||
mut_repo.insert_git_ref("refs/heads/branch1".to_string(), commit1.id().clone());
|
||||
mut_repo.insert_git_ref("refs/tags/tag1".to_string(), commit2.id().clone());
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo.as_repo_ref(), "git_refs()"),
|
||||
vec![commit2.id().clone(), commit1.id().clone()]
|
||||
);
|
||||
// Two refs pointing to the same commit does not result in a duplicate in the
|
||||
// revset
|
||||
mut_repo.insert_git_ref("refs/tags/tag2".to_string(), commit2.id().clone());
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo.as_repo_ref(), "git_refs()"),
|
||||
vec![commit2.id().clone(), commit1.id().clone()]
|
||||
);
|
||||
|
||||
tx.discard();
|
||||
}
|
||||
|
||||
#[test_case(false ; "local store")]
|
||||
#[test_case(true ; "git store")]
|
||||
fn test_evaluate_expression_obsolete(use_git: bool) {
|
||||
|
|
Loading…
Reference in a new issue