264 Commits

Author SHA1 Message Date
Ilya Grigoriev
096538ba18 revsets: stop jj parsing br as a git_ref refs/heads/br
Use `br@git` instead.

Before, if there is not a local branch `br`, jj tried to resolve
it as a git ref `refs/heads/br`. Unchanged from before, `br` can
still be resolved as a tag `refs/tag/br`.
2023-06-12 14:31:44 -07:00
Ilya Grigoriev
a483252cf2 revset: allow checking out git-tracking (@git) branches 2023-06-12 14:31:44 -07:00
Waleed Khan
23a4124d20 feat(revset): suggest similar branch names 2023-06-05 11:11:17 -05:00
Waleed Khan
f61cbae022 refactor(revset): move collect_similar from cli_util to revset 2023-06-05 11:11:17 -05:00
Martin von Zweigbergk
fb17e6a50e revset: use different errors for ambiguous commit/change IDs
I made a typo and got something like this:

```
Error: Commit or change id prefix "wl" is ambiguous
```

Since we can tell commit ids from change ids these days, let's make
the error message say which kind of id it is. Changing that also kind
of forced me to make a special error for empty strings. Otherwise we
would have to arbitrarily say that an empty string is a commit id or
change id. A specific error message for empty strings seems helpful,
so that's probably for the better anyway.
2023-05-31 06:28:32 -07:00
Aaron Bull Schaefer
d10af403a5 cleanup: fix minor typos in function names
> error: `mutliple` should be `multiple`
> error: `visble` should be `visible`

Found via typos:
- https://github.com/crate-ci/typos
2023-05-25 08:43:06 -07:00
Yuya Nishihara
6ba684a395 index: replace use of walk_revs() with revset API
I've added a helper function because the construction of the range expression
is a bit noisy. It could be a Repo method, but I don't want to make it a
default implementation of the trait method.

revset::walk_revs() let the caller handle RevsetEvaluationError since the
evaluation engine may error out even with such a trivial query. For now, most
callers just .unwrap() the error as before.
2023-05-24 01:02:37 +09:00
Yuya Nishihara
0b2f0eca05 revset: add Revset::count() API
The default-engine implementation is pretty much the same as iter().count(),
but custom engine may have an optimal path.
2023-05-24 01:02:37 +09:00
Yuya Nishihara
5b568cabcc revset: add iterator of (CommitId, ChangeId) pairs, use it in id_index
There are a few more places where we need these pairs.
2023-05-24 01:02:37 +09:00
Yuya Nishihara
8d56b199bc revset: initialize with default prefix resolver
Since repo is passed as argument, we can define the default resolver as
a plain function.
2023-05-12 21:31:29 +09:00
Yuya Nishihara
f58beca760 revset: move resolve_symbol() to tests
It's no longer used in library code.
2023-05-12 21:31:29 +09:00
Martin von Zweigbergk
916b00c33e id_prefix: remove repo field from IdPrefixContext
By passing the repo as argument to the methods instead, we can remove
the `repo` field and the associated lifetime. Thanks to Yuya for the
suggestion.
2023-05-11 23:41:24 -07:00
Martin von Zweigbergk
5612a3106c revset: use IdPrefixContext for resolving commit/change ids
This is another step towards resolving abbreviated commit ids within a
configured revset.
2023-05-11 23:41:24 -07:00
Martin von Zweigbergk
f66efcf6f9 revset: inline resolution of change/commit ids
This prepares for adding callbacks to resolve these ids.
2023-05-11 23:41:24 -07:00
Martin von Zweigbergk
efd743339c revset: don't allow symbols in RevsetExpression::resolve()
When creating `RevsetExpression` programmatically, I think we should
use commit ids instead of symbols in the expression. This commit adds
a check for that by using a `SymbolResolver` that always errors
out.
2023-05-11 23:41:24 -07:00
Martin von Zweigbergk
99e9cd70d1 cli: make WorkspaceCommandHelper create SymbolResolver
I would eventually want the `SymbolResolver` to be customizable (in
custom `jj` binaries), so we want to make sure we always use the
customized version of it.

I left `RevsetExpression::resolve()` unchanged. I consider that to be
for programmatically created expressions.
2023-05-11 23:41:24 -07:00
Martin von Zweigbergk
5e7c57c527 revset: introduce a trait for resolving symbols
I'd like to make the symbol resolution more flexible, both so we can
support customizing it (in custom `jj` binaries) and so we can use it
for resolving short prefixes within a small revset.
2023-05-11 23:41:24 -07:00
Martin von Zweigbergk
b11d38fdf8 revset: delete obsolete comment about ambiguous change/commit ids
Commit ids and change ids or prefixes of either are never ambiguous
since we started using k-z for change ids.
2023-05-03 16:23:14 -07:00
Martin von Zweigbergk
9cf0440aef revset: elide some lifetimes (reported by IntelliJ) 2023-05-03 16:23:14 -07:00
Yuya Nishihara
837e8aa81a revset: add substitution rule for nested descendants/children
The substitution rule and tests are copied from ancestors/parents. The backend
logic will be reimplemented later. For now, it naively repeats children().
2023-04-24 20:45:13 +09:00
Yuya Nishihara
32253fed5e revset: replace children node with descendants of generation 1..2 2023-04-24 20:45:13 +09:00
Yuya Nishihara
a99b82c634 revset: add generation parameter to descendants node
This is a minimal change to replace Children with Descendants. A generation
parameter could be added to RevsetExpression::DagRange, but it's not needed
as of now.
2023-04-24 20:45:13 +09:00
Yuya Nishihara
f6570486e0 revset: add descendants node to expression, resolve it later
I'll add a substitution rule that folds (x+)+, and 'Descendants { roots }'
is easier to process than 'DagRange { roots, heads }'.
2023-04-24 20:45:13 +09:00
Martin von Zweigbergk
e492548772 revset: bump generation numbers in API to 64 bits
A chain of 4 billion commits is a lot, but it's not out of the
question, so let's support it. The current default index will not be
able to handle that many commits, so I let that still use 32-bit
integers.
2023-04-12 21:18:49 -07:00
Yuya Nishihara
5351371d51 revset: resolve visible heads prior to evaluation 2023-04-10 00:39:58 +09:00
Yuya Nishihara
7e1e9efa38 revset: resolve "all()" prior to evaluation 2023-04-10 00:39:58 +09:00
Yuya Nishihara
f43f0d24b8 revset: resolve candidates of children set prior to evaluation 2023-04-10 00:39:58 +09:00
Yuya Nishihara
7974269bab revset: remove None variant from resolved enum, use Commits([]) instead
We'll remove All, so it makes sense to not have None either.
2023-04-10 00:39:58 +09:00
Yuya Nishihara
0fcc13a6f4 revset: make resolve() return different type describing evaluation plan
New ResolvedExpression enum ensures that the evaluation engine doesn't have
to know the symbol resolution details. In this commit, I've moved Filter
and NotIn resolution to resolve_visibility(). Implicit All/VisibleHeads
resolution will be migrated later.

It's tempting to combine resolve_symbols() and resolve_visibility() to get
rid of panic!()s, but the resolution might have to be two passes to first
resolve&collect explicit commit ids, and then substitute "all()" with
"(:visible_heads())|commit_id|..". It's also possible to apply some tree
transformation after symbol resolution.
2023-04-10 00:39:58 +09:00
Yuya Nishihara
6c2525cb93 revset: add "resolve" method to RevsetExpression, always call it
I'll make the resolution stage mandatory, and have it return a "resolved"
type. RevsetExpression::evaluate() will be moved to the "resolved" type.
2023-04-10 00:39:58 +09:00
Yuya Nishihara
6d9b836d10 revset: extract unresolved commit references to separate enum
This makes it clear what should be resolved at resolve_symbols(). Symbol
is a bit special while parsing function arguments, but it's no different
than the other unresolved references at expression level.
2023-04-10 00:39:58 +09:00
Yuya Nishihara
fc65b00020 revset: extract CommitId resolution to function
I'm going to merge unresolved variants as RevsetExpression::CommitRef(_).
This prepares for the change.
2023-04-10 00:39:58 +09:00
Martin von Zweigbergk
24a512683b revset: add a revset function for finding commits with conflicts
This adds `conflict()` revset that selects commits with conflicts. We
may want to extend it later to consider only conflicts at certain
paths.
2023-04-06 16:46:21 -07:00
Martin von Zweigbergk
e1c57338a1 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.
2023-04-03 23:46:34 -07:00
Yuya Nishihara
0bfdbcaa1e revset: don't rewrite '~set & filter' as difference
Since filter is slow in general, its input set should be minimized. This has
measurable impact on artificial query like '~(v0.4.0..) & author(_)'. If it
were evaluated as a difference of sets, all commits would have to be loaded.
2023-04-04 15:21:21 +09:00
Yuya Nishihara
3927c01d08 revset: make error type opaque to try_transform_expression()
It no longer handles RevsetResolutionError.
2023-04-03 10:55:03 +09:00
Yuya Nishihara
f1e2d19d57 revset: fully consume Present(_) node by resolve_symbols()
Since resolve_symbols() now removes Present(_) node, it make sense to
handle symbol resolution error there. That's why I added a "pre" callback
to try_transform_expression().

Perhaps, "operation" scope (#1283) can be implemented in a similar way,
(but somehow need to resolve operation id and call repo.reload_at(op).)
2023-04-03 10:55:03 +09:00
Yuya Nishihara
aeb93c7591 revset: insert pre-order callback that can terminate transformation early
This will be a hook for resolve_symbols() to transform Present(_) subtree.
2023-04-03 10:55:03 +09:00
Yuya Nishihara
feaad6b5fa revset: add type alias for Option<Rc<RevsetExpression>>
I'm going to parameterize error type of TransformResult, and the result type
will be replaced with Result<TransformedExpression, E>.
2023-04-03 10:55:03 +09:00
Yuya Nishihara
c28d2d7784 revset: split RevsetError into RevsetResolution/EvaluationError
This makes it clear that RevsetExpression::Present node is noop at the
evaluation stage.

RevsetEvaluationError::StoreError is unused right now, but I'm not sure if
it should be removed. It makes some sense that evaluate() can propagate
StoreError as it has access to the store.
2023-04-03 10:55:03 +09:00
Yuya Nishihara
429562ca2f revset: implement Debug for RevsetImpl and add trait bound accordingly 2023-04-02 22:54:46 +09:00
Martin von Zweigbergk
3546cc1bf6 revset: pass in store, index, and heads instead of whole Repo
The `Repo` is a higher-level type that the index shouldn't have to
know about. With this change, a custom revset implementation should be
able evaluate the revset on a server without knowing which repo it
refers to.
2023-03-30 20:15:45 -07:00
Martin von Zweigbergk
3ff1ab520b revset: remove public_heads()
The `public_heads()` revset only contains the root commit in
practice. I'm not sure what we want to do about phases, but since we
don't have any real support for them yet, let's just remove this
revset. I didn't update the changelog because we don't seem to have
documented the revset function (and it seems unlikely that users who
found out about it found it useful enough to use it when they could
just use `root`).
2023-03-30 20:15:45 -07:00
Martin von Zweigbergk
2a3d402d0c revset: also resolve branches(), tags(), etc. when resolving symbols
This is another step towards removing the `Repo` argument from
`Index::evaluate_revset()`.
2023-03-30 20:15:45 -07:00
Yuya Nishihara
0532301e03 revset: add latest(candidates, count) predicate
This serves the role of limit() in Mercurial. Since revsets in JJ is
(conceptually) an unordered set, a "limit" predicate should define its
ordering criteria. That's why the added predicate is named as "latest".

Closes #1110
2023-03-25 23:48:50 +09:00
Yuya Nishihara
185549f031 revset: extract helper to parse literal to e.g. usize 2023-03-25 23:48:50 +09:00
Martin von Zweigbergk
ce5c90b4e5 revset: use Index::has_id() for checking if a commit has been indexed
This avoids another use of `IndexEntry`.
2023-03-24 10:09:40 -07:00
Martin von Zweigbergk
75605e36af revset: iterate over commit ids instead of index entries
There are no remaining places where we iterate over a revset and need
the `IndexEntry`s, so we can now make `Revset::iter()` yield
`CommitId`s instead.
2023-03-23 21:58:15 -07:00
Martin von Zweigbergk
68cff2fa22 repo: get change id index from revset instead of building it in repo
This replaces the direct use of `IdIndex` in `ReadonlyRepo` by use of
`Revset::change_id_index()`.

I made the `Index` trait require `Send` and `Sync` in order to be able
to store an instance of it in `ReadonlyRepo` (via `ChangeIdIndex`) and
still have that be `Send` and `Sync`. We could alternatively store the
`ChangeIdIndex` in a `Mutex`. Now that will be up to the
`ChangeIdIndex` instead.
2023-03-23 20:49:15 -07:00
Martin von Zweigbergk
27a7fccefa revset: add a method returning a change id index
One of the remaining places we depend on index positions is when
creating a `ChangeIdIndex`. This moves that into the revset engine
(which is coupled to the commit index implementation) by adding a
`Revset::change_id_index()` method. We will also use this function
later when add support for resolving change id prefixes within a small
revset.

The current implementation simply creates an in-memory index using the
existing `IdIndex` we have in `repo.rs`.

The custom implementation at Google might do the same for small
revsets that are available on the client, but for revsets involving
many commits on the server, it might use a suboptimmal implementation
that uses longer-than-necessary prefixes for performance reasons. That
can be done by querying a server-side index including changes not in
the revset, and then verifying that the resulting commits are actually
in the revset.
2023-03-23 20:49:15 -07:00