revsets: add branches() and tags() functions

The `branches()` function resolves to all "adds" on both local and
remote branches.
This commit is contained in:
Martin von Zweigbergk 2021-08-04 11:51:41 -07:00
parent 15132a1166
commit aeab6660d9
2 changed files with 56 additions and 3 deletions

View file

@ -243,11 +243,11 @@ By default, `jj log` lists all revisions (commits) in the repo that have not
been rewritten (roughly speaking). We can use the `-r` flag to restrict which
revisions we want to list. The flag accepts a "revset", which is an expression
in a simple language for specifying revision. For example, `@` refers to the
working copy commit, `root` refers to the root commit, `git_refs()` refers to
all commits pointed to by git refs. We can combine expression with `|` for
working copy commit, `root` refers to the root commit, `branches()` refers to
all commits pointed to by branches. We can combine expression with `|` for
union, `&` for intersection and `-` for difference. For example:
```shell script
$ jj log -r '@ | root | git_refs()'
$ jj log -r '@ | root | branches()'
@ 192b456b024b f39aeb1a0200 martinvonz@google.com 2021-05-23 23:10:27.000 -07:00
:
o 080a9b37ff7e 6a91b4ba16c7 martinvonz@google.com 2021-05-23 22:08:37.000 -07:00 main

View file

@ -192,6 +192,8 @@ pub enum RevsetExpression {
},
AllHeads,
PublicHeads,
Branches,
Tags,
GitRefs,
NonObsoleteHeads(Rc<RevsetExpression>),
ParentCount {
@ -495,6 +497,26 @@ fn parse_function_expression(
})
}
}
"branches" => {
if arg_count == 0 {
Ok(RevsetExpression::Branches)
} else {
Err(RevsetParseError::InvalidFunctionArguments {
name,
message: "Expected 0 arguments".to_string(),
})
}
}
"tags" => {
if arg_count == 0 {
Ok(RevsetExpression::Tags)
} else {
Err(RevsetParseError::InvalidFunctionArguments {
name,
message: "Expected 0 arguments".to_string(),
})
}
}
"git_refs" => {
if arg_count == 0 {
Ok(RevsetExpression::GitRefs)
@ -969,6 +991,37 @@ pub fn evaluate_expression<'repo>(
index_entries.sort_by_key(|b| Reverse(b.position()));
Ok(Box::new(EagerRevset { index_entries }))
}
RevsetExpression::Branches => {
let index = repo.index();
let mut index_entries = vec![];
for branch_target in repo.view().branches().values() {
if let Some(local_target) = &branch_target.local_target {
for id in local_target.adds() {
index_entries.push(index.entry_by_id(&id).unwrap());
}
}
for remote_target in branch_target.remote_targets.values() {
for id in remote_target.adds() {
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::Tags => {
let index = repo.index();
let mut index_entries = vec![];
for ref_target in repo.view().tags().values() {
for id in ref_target.adds() {
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::GitRefs => {
let index = repo.index();
let mut index_entries = vec![];