forked from mirrors/jj
revset: split out no-args head()
to visible_heads()
The `heads()` revset function with one argument is the counterpart to `roots()`. Without arguments, it returns the visible heads in the repo, i.e. `heads(all())`. The two use cases are quite different, and I think it would be good to clarify that the no-arg form returns the visible heads, so let's split that out to a new `visible_heads()` function.
This commit is contained in:
parent
982062bd75
commit
e1c57338a1
6 changed files with 23 additions and 20 deletions
|
@ -23,6 +23,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
* The minimum supported Rust version (MSRV) is now 1.64.0.
|
||||
|
||||
* The `heads()` revset function was split up into two functions. `heads()`
|
||||
without arguments is now called `visible_heads()`. `heads()` with one argument
|
||||
is unchanged.
|
||||
|
||||
### New features
|
||||
|
||||
* `jj git push --deleted` will remove all locally deleted branches from the remote.
|
||||
|
|
|
@ -104,9 +104,8 @@ revsets (expressions) as arguments.
|
|||
* `git_refs()`: All Git ref targets as of the last import. If a Git ref
|
||||
is in a conflicted state, all its possible targets are included.
|
||||
* `git_head()`: The Git `HEAD` target as of the last import.
|
||||
* `heads([x])`: Commits in `x` that are not ancestors of other commits in `x`.
|
||||
If `x` was not specified, it selects all visible heads (as if you had said
|
||||
`heads(all())`).
|
||||
* `visible_heads()`: All visible heads (same as `heads(all())`).
|
||||
* `heads(x)`: Commits in `x` that are not ancestors of other commits in `x`.
|
||||
* `roots(x)`: Commits in `x` that are not descendants of other commits in `x`.
|
||||
* `latest(x[, count])`: Latest `count` commits in `x`, based on committer
|
||||
timestamp. The default `count` is 1.
|
||||
|
|
|
@ -627,7 +627,7 @@ impl<'index, 'heads> EvaluationContext<'index, 'heads> {
|
|||
// but if it does, the heads set could be extended to include the commits
|
||||
// (and `remote_branches()`) specified in the revset expression. Alternatively,
|
||||
// some optimization rules could be removed, but that means `author(_) & x`
|
||||
// would have to test `:heads() & x`.
|
||||
// would have to test `:visble_heads() & x`.
|
||||
let walk = self.composite_index.walk_revs(self.visible_heads, &[]);
|
||||
Ok(Box::new(RevWalkRevset { walk }))
|
||||
}
|
||||
|
|
|
@ -798,19 +798,19 @@ static BUILTIN_FUNCTION_MAP: Lazy<HashMap<&'static str, RevsetFunction>> = Lazy:
|
|||
Ok(RevsetExpression::all())
|
||||
});
|
||||
map.insert("heads", |name, arguments_pair, state| {
|
||||
let ([], [opt_arg]) = expect_arguments(name, arguments_pair)?;
|
||||
if let Some(arg) = opt_arg {
|
||||
let candidates = parse_expression_rule(arg.into_inner(), state)?;
|
||||
Ok(candidates.heads())
|
||||
} else {
|
||||
Ok(RevsetExpression::visible_heads())
|
||||
}
|
||||
let arg = expect_one_argument(name, arguments_pair)?;
|
||||
let candidates = parse_expression_rule(arg.into_inner(), state)?;
|
||||
Ok(candidates.heads())
|
||||
});
|
||||
map.insert("roots", |name, arguments_pair, state| {
|
||||
let arg = expect_one_argument(name, arguments_pair)?;
|
||||
let candidates = parse_expression_rule(arg.into_inner(), state)?;
|
||||
Ok(candidates.roots())
|
||||
});
|
||||
map.insert("visible_heads", |name, arguments_pair, _state| {
|
||||
expect_no_arguments(name, arguments_pair)?;
|
||||
Ok(RevsetExpression::visible_heads())
|
||||
});
|
||||
map.insert("branches", |name, arguments_pair, state| {
|
||||
let ([], [opt_arg]) = expect_arguments(name, arguments_pair)?;
|
||||
let needle = if let Some(arg) = opt_arg {
|
||||
|
@ -2046,7 +2046,7 @@ mod tests {
|
|||
assert_eq!(parse("foo | -"), Err(RevsetParseErrorKind::SyntaxError));
|
||||
// Space is allowed around infix operators and function arguments
|
||||
assert_eq!(
|
||||
parse(" description( arg1 ) ~ file( arg1 , arg2 ) ~ heads( ) "),
|
||||
parse(" description( arg1 ) ~ file( arg1 , arg2 ) ~ visible_heads( ) "),
|
||||
Ok(
|
||||
RevsetExpression::filter(RevsetFilterPredicate::Description("arg1".to_string()))
|
||||
.minus(&RevsetExpression::filter(RevsetFilterPredicate::File(
|
||||
|
@ -2205,7 +2205,7 @@ mod tests {
|
|||
))
|
||||
);
|
||||
assert_eq!(
|
||||
parse("description(heads())"),
|
||||
parse("description(visible_heads())"),
|
||||
Err(RevsetParseErrorKind::InvalidFunctionArguments {
|
||||
name: "description".to_string(),
|
||||
message: "Expected function argument of type string".to_string()
|
||||
|
|
|
@ -600,10 +600,10 @@ fn test_evaluate_expression_heads(use_git: bool) {
|
|||
vec![commit3.id().clone()]
|
||||
);
|
||||
|
||||
// Heads of all commits is the set of heads in the repo
|
||||
// Heads of all commits is the set of visible heads in the repo
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo, "heads(all())"),
|
||||
resolve_commit_ids(mut_repo, "heads()")
|
||||
resolve_commit_ids(mut_repo, "visible_heads()")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1187,7 +1187,7 @@ fn test_evaluate_expression_visible_heads(use_git: bool) {
|
|||
let commit3 = graph_builder.commit_with_parents(&[&commit1]);
|
||||
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo, "heads()"),
|
||||
resolve_commit_ids(mut_repo, "visible_heads()"),
|
||||
vec![commit3.id().clone(), commit2.id().clone()]
|
||||
);
|
||||
}
|
||||
|
@ -1626,7 +1626,7 @@ fn test_evaluate_expression_description(use_git: bool) {
|
|||
);
|
||||
// Searches only among candidates if specified
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo, "heads() & description(\"commit 2\")"),
|
||||
resolve_commit_ids(mut_repo, "visible_heads() & description(\"commit 2\")"),
|
||||
vec![]
|
||||
);
|
||||
}
|
||||
|
@ -1692,7 +1692,7 @@ fn test_evaluate_expression_author(use_git: bool) {
|
|||
);
|
||||
// Searches only among candidates if specified
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo, "heads() & author(\"name2\")"),
|
||||
resolve_commit_ids(mut_repo, "visible_heads() & author(\"name2\")"),
|
||||
vec![]
|
||||
);
|
||||
// Filter by union of pure predicate and set
|
||||
|
@ -1766,7 +1766,7 @@ fn test_evaluate_expression_committer(use_git: bool) {
|
|||
);
|
||||
// Searches only among candidates if specified
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo, "heads() & committer(\"name2\")"),
|
||||
resolve_commit_ids(mut_repo, "visible_heads() & committer(\"name2\")"),
|
||||
vec![]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ fn test_bad_function_call() {
|
|||
1 | heads(foo, bar)
|
||||
| ^------^
|
||||
|
|
||||
= Invalid arguments to revset function "heads": Expected 0 to 1 arguments
|
||||
= Invalid arguments to revset function "heads": Expected 1 arguments
|
||||
"###);
|
||||
|
||||
let stderr = test_env.jj_cmd_failure(&repo_path, &["log", "-r", "latest(a, not_an_integer)"]);
|
||||
|
|
Loading…
Reference in a new issue