revsets: add git_head() revset

This is part of #44.
This commit is contained in:
Martin von Zweigbergk 2021-11-28 23:02:35 -08:00
parent 626fbee0dd
commit f1bfe85f45
2 changed files with 43 additions and 0 deletions

View file

@ -202,6 +202,7 @@ pub enum RevsetExpression {
RemoteBranches, RemoteBranches,
Tags, Tags,
GitRefs, GitRefs,
GitHead,
ParentCount { ParentCount {
candidates: Rc<RevsetExpression>, candidates: Rc<RevsetExpression>,
parent_count_range: Range<u32>, parent_count_range: Range<u32>,
@ -260,6 +261,10 @@ impl RevsetExpression {
Rc::new(RevsetExpression::GitRefs) Rc::new(RevsetExpression::GitRefs)
} }
pub fn git_head() -> Rc<RevsetExpression> {
Rc::new(RevsetExpression::GitHead)
}
/// Commits in `self` that don't have descendants in `self`. /// Commits in `self` that don't have descendants in `self`.
// TODO: Perhaps this should be renamed to just `heads()` and the current // TODO: Perhaps this should be renamed to just `heads()` and the current
// `heads()` should become `visible_heads()` or `current_heads()`. // `heads()` should become `visible_heads()` or `current_heads()`.
@ -644,6 +649,16 @@ fn parse_function_expression(
}) })
} }
} }
"git_head" => {
if arg_count == 0 {
Ok(RevsetExpression::git_head())
} else {
Err(RevsetParseError::InvalidFunctionArguments {
name,
message: "Expected 0 arguments".to_string(),
})
}
}
"merges" => { "merges" => {
if arg_count > 1 { if arg_count > 1 {
return Err(RevsetParseError::InvalidFunctionArguments { return Err(RevsetParseError::InvalidFunctionArguments {
@ -1156,6 +1171,10 @@ pub fn evaluate_expression<'repo>(
} }
Ok(revset_for_commit_ids(repo, &commit_ids)) Ok(revset_for_commit_ids(repo, &commit_ids))
} }
RevsetExpression::GitHead => {
let commit_ids = repo.view().git_head().into_iter().collect_vec();
Ok(revset_for_commit_ids(repo, &commit_ids))
}
RevsetExpression::Description { needle, candidates } => { RevsetExpression::Description { needle, candidates } => {
let candidates = candidates.evaluate(repo)?; let candidates = candidates.evaluate(repo)?;
let repo = repo; let repo = repo;

View file

@ -980,6 +980,30 @@ fn test_evaluate_expression_git_refs(use_git: bool) {
); );
} }
#[test_case(false ; "local backend")]
#[test_case(true ; "git backend")]
fn test_evaluate_expression_git_head(use_git: bool) {
let settings = testutils::user_settings();
let test_workspace = testutils::init_repo(&settings, use_git);
let repo = &test_workspace.repo;
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);
// Can get git head when it's not set
assert_eq!(
resolve_commit_ids(mut_repo.as_repo_ref(), "git_head()"),
vec![]
);
mut_repo.set_git_head(commit1.id().clone());
assert_eq!(
resolve_commit_ids(mut_repo.as_repo_ref(), "git_head()"),
vec![commit1.id().clone()]
);
}
#[test_case(false ; "local backend")] #[test_case(false ; "local backend")]
#[test_case(true ; "git backend")] #[test_case(true ; "git backend")]
fn test_evaluate_expression_branches(use_git: bool) { fn test_evaluate_expression_branches(use_git: bool) {