Glob patterns will be enabled by default globally. Since this will be a big
breaking change in revsets, this patch adds a config knob to turn the new
default on/off.
Deprecation warnings will be emitted for default "substring:" patterns. This
change will suppress them. Since "glob:" will be the new default, I made these
tests use "glob:" when both "exact:" and "glob:" work.
Tests for the revset filter functions aren't updated.
After the previous commit, `MergedTree` and `MergedTreeId` are almost
identical, with the only difference being that `MergedTree` is attached
to a `Store` instance. `MergedTreeId` is also equivalent to
`Merge<TreeId>`, since it is just a wrapper around it.
In the future, `MergedTree` might contain additional metadata like
conflict labels. Therefore, I replaced `MergedTreeId` with `MergedTree`
wherever I think it would be required to pass this additional metadata,
or where the additional methods provided by `MergedTree` would be
useful. In any remaining places, I replaced it with `Merge<TreeId>`.
I also renamed some of the `tree_id()` methods to `tree_ids()` for
consistency, since now they return a merge of individual tree IDs
instead of a single "merged tree ID". Similarly, `MergedTree` no longer
has an `id()` method, since tree IDs won't fully identify a `MergedTree`
once it contains additional metadata.
The default remote parameter of remote_bookmarks() will be derived from this
parameter. It doesn't make sense to exclude @git bookmarks if the backend isn't
Git. It's also nice that parsing tests don't depend on the feature flag.
A typical use case is to query bookmarked revisions ignoring auto-generated
bookmarks. `bookmarks() ~ bookmarks(x)` doesn't work because a revision may have
multiple bookmarks. It's also nice that we can document the default of
`remote_bookmarks()` as `remote_bookmarks(remote=~exact:"git")`.
Closes#7665
With `all:` having gone away, some users (including me) had been using it
to enforce an invariant: by omitting it, an expression was guaranteed to
yield exactly one result. For example, this is important when using tools
like `jj rebase -B/-A`
Instead, let's fix that case by building that functionality into the
revset language itself. The previous behavior can now be enforced via
the term `exactly(x, 1)`
In the future, `n` could also be a range.
Signed-off-by: Austin Seipp <aseipp@pobox.com>
The current implementation does linear search, which I think is good assuming
the size of the changed paths set is usually small. The next costly part of "jj
log PATH" is commit.empty() template on merge commits (#5411). We'll need a
public API to query changed-path index to optimize it.
This optimization is already done for `heads(ancestors(x) & ...)`, so I
think it makes sense to extend it to `first_ancestors()` as well. This
is especially important if the expression involves a filter that
requires reading commits. For instance, in the nixpkgs repo, evaluating
`heads(first_ancestors(@) & description(jujutsu))` takes 2.6 seconds on
my machine before this optimization, and only 0.2 seconds after.
This adds a version of the `bisect()` revset that simply takes the
midpoint of the input set when iterated over. That's correct in linear
history and probably usually good enough in non-linear history too. We
can improve it later. I think it's valuable to have this building
block even in an imperfect state.
We don't have an intuitive way to search for non-UTF-8 strings with
diff_contains(), but this allows the user to search for UTF-8 patterns inside
files of arbitrary encoding (such as text logs.)
We could instead make .is_match() accept AsRef<[u8]>, but I think an explicit
bytes method is better. haystack is usually a string.
It's surprising that a symbol expression may be resolved to multiple revisions,
and that's one of the reason we require all: modifier in some places. Let's make
a symbol resolution fail in that case so we can deprecate the all: syntax.
The new error hints are a bit less informative, but I don't want to implement
ad-hoc formatting for resolve_some_revsets_default_single(). The user will have
to review the graph anyway in order to resolve divergence/conflicts.
Closes#5632
Basically, these functions work in the same way as bookmarks()/tags(). They
restrict the namespace to search the specified symbol, and unmatched symbol
isn't an error. One major difference is that ambiguous prefix triggers an error.
That's because ambiguous prefix should logically select all matching entries,
whereas the underlying functions don't provide this behavior. It's also unclear
whether we would want to get all matching commits by commit_id(prefix:'').
#5632
Since the extension point is now provided by SymbolResolverExtension, this
abstraction isn't useful anymore. This change will probably help implement
commit/change_id(pattern) functions. If the resolver were abstract type, we
would have to add resolve_commit/change_id() methods separately.
The semantics is similar to experimental.directaccess=true in Mercurial. Hidden
revisions and their ancestors become temporarily available. This means all() is
not exactly the same as ::visible_heads(). The latter never includes hidden
revisions.
We could instead transform all() to (all() | referenced_commits). However, this
wouldn't work if expressions like ::hidden are intersected/united with filters,
all(), etc.
Fixes#5871
This was originally suggested by Scott Taylor in #6679. I thought filter
intersections would have been externalized to the set intersections, but that
was wrong. Since union of filter intersections (e.g. `(f1 | f2 & f3) & s4`) is
evaluated as `filter_within(s4, f1 | f2 & f3)`, it doesn't make sense to convert
`f2 & f3` back to set intersection `filter_within(all(), f2) & f3`.
Resolves#6656.
Currently, evaluating an expression like `heads(::@ ~ empty())` requires
iterating over all commits in `::@` and checking the predicate against
each commit, which can be very slow. This PR implements an optimization
to convert expressions to the form `heads(x..y & filter)` when it is
possible to do so efficiently. Expressions of this form can be evaluated
using a specialized algorithm which terminates iteration early without
checking all commits.
Benchmark results on Git repo:
```
revsets/heads(author(peff)) 97.248% improvement
revsets/heads(::v2.40.0) 98.467% improvement
```
Just for completeness. Case-insensitive search can be achieved by (?i), but doc
and hint suggest that the -i suffix works for all pattern types.
Closes#6653
We haven't had any reports of problems from people who opted in. Since
it's early in the release cycle now, let's now test it on everyone who
builds from head, so we get almost a month of testing from those
people before it's enabled by default in a released version.
This impacts lots of test cases because the change-id header is added
to the Git commit. Most are uninteresting. `test_git_fetch` now sees
some divergent changes where it used to see only divergent bookmarks,
which makes sense.
The logic is similar to the color-words diff's. We first resolve trivial
conflicts, then compare each hunk of Merge<&BStr> type. We also apply the same
optimization as the resolved case to minimize lines to be merged and diffed.
I think this makes more sense because WorkspaceId is currently a human-readable
name. In error/status messages, workspace names are now printed in revset
syntax.
New WorkspaceId types do not implement Default. It would be weird if string-like
type had non-empty Default::default(). The DEFAULT constant is provided instead.
This allows callers to mutate RevsetParseContext if needed.
RevsetParseContext was changed to an opaque struct at 4e0abf0631 "revset: make
RevsetParseContext opaque." I think the intent there was to hide implementation
details from revset extension functions. This is now achieved by opaque
LoweringContext.
Another reason of this change is that aliases_map is no longer needed when
transforming AST to UserRevsetExpression.
I tried to minimize this patch, but it seemed rather complicated than porting
most callers all at once. Remote management functions in git.rs are unchanged.
They'll be ported separately.
With this change, many non-template bookmark/remote name outputs should be
rendered in revset syntax.
The CI seems to correctly use rustc 1.84.1 (and not 1.84.0) with this.
For reference, we last updated the MSRV to 1.76 in 5b517b5. According to
https://releases.rs/docs/1.76.0/, this was when it barely became stable.
`flake.nix` seems to be using a nightly toolchain now, so it seems there
is no need to update the version there.
The more precise clippy command used was:
cargo clippy --workspace --all-targets --fix