mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-28 23:32:41 +00:00
revset: split out a new remote_branches()
from branches()
It seems useful to be able to use `remote_branches()` in revsets e.g. for filtering out commits known on remotes.
This commit is contained in:
parent
ebcd946732
commit
8465a578be
2 changed files with 169 additions and 0 deletions
|
@ -198,6 +198,7 @@ pub enum RevsetExpression {
|
|||
Heads,
|
||||
PublicHeads,
|
||||
Branches,
|
||||
RemoteBranches,
|
||||
Tags,
|
||||
GitRefs,
|
||||
ParentCount {
|
||||
|
@ -246,6 +247,10 @@ impl RevsetExpression {
|
|||
Rc::new(RevsetExpression::Branches)
|
||||
}
|
||||
|
||||
pub fn remote_branches() -> Rc<RevsetExpression> {
|
||||
Rc::new(RevsetExpression::RemoteBranches)
|
||||
}
|
||||
|
||||
pub fn tags() -> Rc<RevsetExpression> {
|
||||
Rc::new(RevsetExpression::Tags)
|
||||
}
|
||||
|
@ -577,6 +582,16 @@ fn parse_function_expression(
|
|||
})
|
||||
}
|
||||
}
|
||||
"remote_branches" => {
|
||||
if arg_count == 0 {
|
||||
Ok(RevsetExpression::remote_branches())
|
||||
} else {
|
||||
Err(RevsetParseError::InvalidFunctionArguments {
|
||||
name,
|
||||
message: "Expected 0 arguments".to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
"tags" => {
|
||||
if arg_count == 0 {
|
||||
Ok(RevsetExpression::tags())
|
||||
|
@ -1098,6 +1113,15 @@ pub fn evaluate_expression<'repo>(
|
|||
index_entries.push(index.entry_by_id(&id).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
index_entries.sort_by_key(|b| Reverse(b.position()));
|
||||
index_entries.dedup();
|
||||
Ok(Box::new(EagerRevset { index_entries }))
|
||||
}
|
||||
RevsetExpression::RemoteBranches => {
|
||||
let index = repo.index();
|
||||
let mut index_entries = vec![];
|
||||
for branch_target in repo.view().branches().values() {
|
||||
for remote_target in branch_target.remote_targets.values() {
|
||||
for id in remote_target.adds() {
|
||||
index_entries.push(index.entry_by_id(&id).unwrap());
|
||||
|
|
|
@ -890,6 +890,151 @@ fn test_evaluate_expression_git_refs(use_git: bool) {
|
|||
tx.discard();
|
||||
}
|
||||
|
||||
#[test_case(false ; "local backend")]
|
||||
#[test_case(true ; "git backend")]
|
||||
fn test_evaluate_expression_branches(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);
|
||||
let commit3 = testutils::create_random_commit(&settings, &repo).write_to_repo(mut_repo);
|
||||
let commit4 = testutils::create_random_commit(&settings, &repo).write_to_repo(mut_repo);
|
||||
|
||||
// Can get branches when there are none
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo.as_repo_ref(), "branches()"),
|
||||
vec![]
|
||||
);
|
||||
// Can get a few branches
|
||||
mut_repo.set_local_branch(
|
||||
"branch1".to_string(),
|
||||
RefTarget::Normal(commit1.id().clone()),
|
||||
);
|
||||
mut_repo.set_local_branch(
|
||||
"branch2".to_string(),
|
||||
RefTarget::Normal(commit2.id().clone()),
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo.as_repo_ref(), "branches()"),
|
||||
vec![commit2.id().clone(), commit1.id().clone()]
|
||||
);
|
||||
// Two branches pointing to the same commit does not result in a duplicate in
|
||||
// the revset
|
||||
mut_repo.set_local_branch(
|
||||
"branch3".to_string(),
|
||||
RefTarget::Normal(commit2.id().clone()),
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo.as_repo_ref(), "branches()"),
|
||||
vec![commit2.id().clone(), commit1.id().clone()]
|
||||
);
|
||||
// Can get branches when there are conflicted refs
|
||||
mut_repo.set_local_branch(
|
||||
"branch1".to_string(),
|
||||
RefTarget::Conflict {
|
||||
removes: vec![commit1.id().clone()],
|
||||
adds: vec![commit2.id().clone(), commit3.id().clone()],
|
||||
},
|
||||
);
|
||||
mut_repo.set_local_branch(
|
||||
"branch2".to_string(),
|
||||
RefTarget::Conflict {
|
||||
removes: vec![commit2.id().clone()],
|
||||
adds: vec![commit3.id().clone(), commit4.id().clone()],
|
||||
},
|
||||
);
|
||||
mut_repo.remove_local_branch("branch3");
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo.as_repo_ref(), "branches()"),
|
||||
vec![
|
||||
commit4.id().clone(),
|
||||
commit3.id().clone(),
|
||||
commit2.id().clone()
|
||||
]
|
||||
);
|
||||
|
||||
tx.discard();
|
||||
}
|
||||
|
||||
#[test_case(false ; "local backend")]
|
||||
#[test_case(true ; "git backend")]
|
||||
fn test_evaluate_expression_remote_branches(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);
|
||||
let commit3 = testutils::create_random_commit(&settings, &repo).write_to_repo(mut_repo);
|
||||
let commit4 = testutils::create_random_commit(&settings, &repo).write_to_repo(mut_repo);
|
||||
|
||||
// Can get branches when there are none
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo.as_repo_ref(), "remote_branches()"),
|
||||
vec![]
|
||||
);
|
||||
// Can get a few branches
|
||||
mut_repo.set_remote_branch(
|
||||
"branch1".to_string(),
|
||||
"origin".to_string(),
|
||||
RefTarget::Normal(commit1.id().clone()),
|
||||
);
|
||||
mut_repo.set_remote_branch(
|
||||
"branch2".to_string(),
|
||||
"private".to_string(),
|
||||
RefTarget::Normal(commit2.id().clone()),
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo.as_repo_ref(), "remote_branches()"),
|
||||
vec![commit2.id().clone(), commit1.id().clone()]
|
||||
);
|
||||
// Two branches pointing to the same commit does not result in a duplicate in
|
||||
// the revset
|
||||
mut_repo.set_remote_branch(
|
||||
"branch3".to_string(),
|
||||
"origin".to_string(),
|
||||
RefTarget::Normal(commit2.id().clone()),
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo.as_repo_ref(), "remote_branches()"),
|
||||
vec![commit2.id().clone(), commit1.id().clone()]
|
||||
);
|
||||
// Can get branches when there are conflicted refs
|
||||
mut_repo.set_remote_branch(
|
||||
"branch1".to_string(),
|
||||
"origin".to_string(),
|
||||
RefTarget::Conflict {
|
||||
removes: vec![commit1.id().clone()],
|
||||
adds: vec![commit2.id().clone(), commit3.id().clone()],
|
||||
},
|
||||
);
|
||||
mut_repo.set_remote_branch(
|
||||
"branch2".to_string(),
|
||||
"private".to_string(),
|
||||
RefTarget::Conflict {
|
||||
removes: vec![commit2.id().clone()],
|
||||
adds: vec![commit3.id().clone(), commit4.id().clone()],
|
||||
},
|
||||
);
|
||||
mut_repo.remove_remote_branch("branch3", "origin");
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo.as_repo_ref(), "remote_branches()"),
|
||||
vec![
|
||||
commit4.id().clone(),
|
||||
commit3.id().clone(),
|
||||
commit2.id().clone()
|
||||
]
|
||||
);
|
||||
|
||||
tx.discard();
|
||||
}
|
||||
|
||||
#[test_case(false ; "local backend")]
|
||||
#[test_case(true ; "git backend")]
|
||||
fn test_evaluate_expression_merges(use_git: bool) {
|
||||
|
|
Loading…
Reference in a new issue