Commit graph

1350 commits

Author SHA1 Message Date
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
baea314fc0 index: get generation number from specific impl in test 2023-03-24 10:09:40 -07:00
Martin von Zweigbergk
a5b79f9b0e index: make topo_order() return commit ids instead of index entries
`IndexEntry` is specific to the default index store; we don't want it
in the interface.
2023-03-24 10:09:40 -07:00
Martin von Zweigbergk
772cb1a0e9 revset: replace an unnecessary iterator adapter by a simple map()
As noted by @yuja in #1423.
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
b5ea79f32e revset: add new graph iterator function for tests
I'm about to make `Revset::iter()` yield just `CommitId`s, but the
tests in `test_default_revset_graph_iterator.rs` need an `IndexEntry`
iterator so they can pass it into `RevsetGraphIterator::new()`. This
commits prepares for the change by adding a
`RevsetImpl::iter_graph_impl()` that returns `RevsetGraphIterator`,
keeping `InternalRevset` still hidden within the revset engine. We
could instead have made that (and `ToPredicateFn`) visible to tests. I
can't say which is better.
2023-03-23 21:58:15 -07:00
Martin von Zweigbergk
c8f387d5b3 revset: pass IndexEntry iterator to graph iterator
The graph iterator is specific to the index implementation, and it
needs access to `IndexEntry`, which `Revset::iter()` will soon not
yield.
2023-03-23 21:58:15 -07:00
Martin von Zweigbergk
0b506d8461 index: remove position-based methods 2023-03-23 20:49:15 -07:00
Martin von Zweigbergk
d4e1156957 repo: move IdIndex to revset engine 2023-03-23 20:49:15 -07:00
Martin von Zweigbergk
13a000caa7 repo: get change id index from revset also for mutable repo
I don't know if we ever resolve revsets in a mutable repo, but now
that we can get a change id index from a revset, it's easier to
implement this functionality that way.
2023-03-23 20:49: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
Martin von Zweigbergk
a65e0e771c revset: remove unnecessary wrapping of every node in RevsetImpl
Thanks to @yuja for the suggestion.
2023-03-23 20:49:15 -07:00
dependabot[bot]
4dc97de928 cargo: bump insta from 1.28.0 to 1.29.0
Bumps [insta](https://github.com/mitsuhiko/insta) from 1.28.0 to 1.29.0.
- [Release notes](https://github.com/mitsuhiko/insta/releases)
- [Changelog](https://github.com/mitsuhiko/insta/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mitsuhiko/insta/compare/1.28.0...1.29.0)

---
updated-dependencies:
- dependency-name: insta
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-23 09:34:27 -07:00
Yuya Nishihara
9d661d6f69 cli: render other kind of revset error suggestion as hint 2023-03-23 23:08:17 +09:00
Yuya Nishihara
ddeb645d7f cli: provide hint for typo of revset function name
This is similar to what Mercurial does. The similarity threshold is copied
from clap, but we might want to adjust it later.
2023-03-23 23:08:17 +09:00
Yuya Nishihara
d3d8afc77b revset: rewrite match table of builtin functions as HashMap
So that we can build a list of function names.
2023-03-23 23:08:17 +09:00
Martin von Zweigbergk
5709822f05 rewrite: keep commits to visit instead of looking up again
Since the commits are cached in `Store`, this doesn't have any impact
on performance, but it's a little simpler.
2023-03-23 04:50:33 -07:00
Martin von Zweigbergk
e81890b319 rewrite: work with commits instead of index entries in setup code
When deciding the order to visit commits to rebase, we currently look
up parents in the index. I'm trying to remove the current `IndexEntry`
type and will probably have revsets iterators yield simply
`CommitId`. Let's therefore look up commit objects here.

I timed this by rewriting all commits in the jj repo. I couldn't
measure any difference. That makes sense since we cache the commits in
`Store` and we would read the commit when rebasing it anyway.
2023-03-23 04:50:33 -07:00
Martin von Zweigbergk
d3cf543abc revset: move revset_for_commits() to test
The function is only used in tests, so it doesn't belong in
`default_revset_engine`. Also, it's not specific to that
implementation, so I rewrote as a revset evaluation.
2023-03-23 04:50:33 -07:00
Martin von Zweigbergk
5f74dd5db3 repo: implement Repo on ReadonlyRepo instead of its Arc
I'd like to be able to pass a `self` of `type `&ReadonlyRepo` to
functions that take a `&dyn Repo`. For that, we need `ReadonlyRepo`
itself to implement `Repo` instead of having `Arc<ReadonlyRepo>`
implement it. I could have solved it in a different way, but the `Arc`
requirement seems like an unnecessary constraint.
2023-03-21 21:43:44 -07:00
Martin von Zweigbergk
d089c22232 repo: move base_repo() off of Repo trait
We only ever call `base_repo()` on `MutableRepo` instances.
2023-03-21 21:43:44 -07:00
Martin von Zweigbergk
ea498df539 repo: when resolving change id prefix, directly return commit ids
The functions resolving a change id to commits currently return a
`Vec<IndexEntry>`. We want to avoid depending on `IndexEntry` and we
only need the commit ids here.
2023-03-21 21:43:44 -07:00
dependabot[bot]
942bb4c8c4 cargo: bump regex from 1.7.1 to 1.7.2
Bumps [regex](https://github.com/rust-lang/regex) from 1.7.1 to 1.7.2.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.7.1...1.7.2)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-21 16:15:53 +00:00
dependabot[bot]
522de4f8c7 cargo: bump thiserror from 1.0.39 to 1.0.40
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.39 to 1.0.40.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.39...1.0.40)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 20:34:15 +00:00
Martin von Zweigbergk
01d7239732 revset: make graph iterator yield commit ids (not index entries)
We only need `CommitId`s, and `IndexEntry` is specific to the default
index implementation.
2023-03-20 01:45:54 -07:00
Martin von Zweigbergk
2f876861ae graphlog: key by commit id (not index position)
The index position is specific to the default index implementation and
we don't want to use it in outside of there. This commit removes the
use of it as a key for nodes in the graphlog.

I timed it on the git.git repo using `jj log -r 'all()' -T commit_id`
(the worst case I can think of) and it slowed down from ~2.02 s to
~2.20 s (~9%).
2023-03-20 01:45:54 -07:00
Martin von Zweigbergk
91df7ec4c5 revset: rename graph iterator test to match implementation 2023-03-20 01:45:54 -07:00
Martin von Zweigbergk
e721a81780 revset: update documentation of Revset::iter()
Since we hid the graph iterator implementation behind
`Revset::iter_graph()`, I don't think we have any callers of
`Revset::iter()` require the iteration to be in index position order,
so let's not promise that. We do want to promise that the iteration is
in topological order with children before parents, however.
2023-03-20 01:45:54 -07:00
Martin von Zweigbergk
f758b646a9 commit_builder: add accessors for most fields
I'd like to be able to access the current committer on a
`CommitBuilder`.
2023-03-19 00:48:05 -07:00
Martin von Zweigbergk
2495c8f27e cargo: update MSRV to 1.64
We need 1.64 to bump `clap` to `4.1`. We don't really need to upgrade
to that, but being on an older version causes minor confusions like
#1393. Rust 1.64 is very close to 6 months old at this point.
2023-03-17 22:44:29 -07:00
Martin von Zweigbergk
70d4a0f42e revset: remove context parameter from evaluate()
The `RevsetWorkspaceContext` argument is now instead used by the new
`resolve_symbol()` function.
2023-03-17 22:42:41 -07:00
Martin von Zweigbergk
d971148e4e revset: move resolve_symbol() back to revset module
The only caller is now in `revset.rs`.
2023-03-17 22:42:41 -07:00
Martin von Zweigbergk
94aec90bee revset: resolve symbols earlier, before passing to revset engine
For large repos, it's useful to be able to use shorter change id and
commit id prefixes by resolving the prefix in a limited subset of the
repo (typically the same subset that you'd want to see in your default
log output). For very large repos, like Google's internal one, the
shortest unique prefix evaluated within the whole repo is practically
useless because it's long enough that the user would want to copy and
paste it anyway.

Mercurial supports this with its `revisions.disambiguatewithin` config
(added in https://www.mercurial-scm.org/repo/hg/rev/503f936489dd). I'd
like to add the same feature to jj. Mercurial's implementation works
by attempting to resolve the prefix in the whole repo and then, if the
prefix was ambiguous, it resolves it in the configured subset
instead. The advantage of doing it that way is that there's no extra
cost of resolving the revset defining the subset if the prefix was not
ambiguous within the whole repo. However, there are two important
reasons to do it differently in jj:

* We support very large repos using custom backends, and it's probably
  cheaper to resolve a prefix within the subset because it can all be
  cached on the client. Resolving the prefix within the whole repo
  requires a roundtrip to the server.

* We want to be able to resolve change id prefixes, which is always
  done in *some* revset. That revset is currently `all()`, i.e. all
  visible commits. Even on local disk, it's probably cheaper to
  resolve a small revset first and then resolve the prefix within that
  than it is to build up the index of all visible change ids.

We could achieve the goal by letting each revset engine respect the
configured subset, but since the solution proposed above makes sense
also for local-disk repos, I think it's better to do it outside of the
revset engine, so all revset engines can share the code.

This commit prepares for the new functionality by moving the symbol
resolution out of `Index::evaluate_revset()`.
2023-03-17 22:42:41 -07:00
Martin von Zweigbergk
1711cb61fb revset: add a Result version of transform_expression_bottom_up()
I'd like to add a stage after optimization for resolving most symbols
to commit IDs, and that needs to be able to fail.
2023-03-17 22:42:41 -07:00
Martin von Zweigbergk
5afe5091a0 revset: add default_ prefix to graph iterator module
The current revset graph iterator is the default one, which the
default revset engine provides.
2023-03-14 05:32:02 -07:00
Martin von Zweigbergk
3871efd2f9 revset: move ReverseRevsetGraphIterator into revset module
The iterator is not specific to the implementation in
`revset_graph_iterator`, so it belongs in the standard `revset`
module.
2023-03-14 05:32:02 -07:00
Martin von Zweigbergk
f62fac24ac revset: move graph iteration onto Revset trait
We want to allow custom revset engines define their own graph
iterator. This commit helps with that by adding a
`Revset::iter_graph()` function that returns an abstract iterator.

The current `RevsetGraphIterator` can be configured to skip or include
transitive edges. It skips them by default and we don't expose option
in the CLI. I didn't bother including that functionality in the new
`iter_graph()` either. At least for now, it will be up to the
implementation whether it includes such edges (it would of course be
free to ignore the caller's request even if we added an option for it
in the API).
2023-03-14 05:32:02 -07:00
Martin von Zweigbergk
28cbd7b1c5 revset: move evaluation into index
This commit adds an `evaluate_revset()` function to the `Index`
trait. It will require some further cleanup, but it already achieves
the goal of letting the index implementation decide which revset
engine to use.
2023-03-14 05:32:02 -07:00
Martin von Zweigbergk
eed0b23009 revset: move current implementation to new module
We want to allow customization of the revset engine, so it can query
server indexes, for example. The current revset implementation will be
our default implementation for now. What's left in the `revset` module
after this commit is mostly parsing code.
2023-03-14 05:32:02 -07:00
dependabot[bot]
1e55fa6c9b cargo: bump whoami from 1.3.0 to 1.4.0
Bumps [whoami](https://github.com/ardaku/whoami) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/ardaku/whoami/releases)
- [Changelog](https://github.com/ardaku/whoami/blob/stable/CHANGELOG.md)
- [Commits](https://github.com/ardaku/whoami/compare/v1.3.0...v1.4.0)

---
updated-dependencies:
- dependency-name: whoami
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-13 10:42:22 -07:00
dependabot[bot]
f5de5707b2 cargo: bump chrono from 0.4.23 to 0.4.24
Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.23 to 0.4.24.
- [Release notes](https://github.com/chronotope/chrono/releases)
- [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chronotope/chrono/compare/v0.4.23...v0.4.24)

---
updated-dependencies:
- dependency-name: chrono
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-13 10:41:49 -07:00
Martin von Zweigbergk
6a57456067 revset: remove is_empty() implementation from trait
Now that there's a single implementation of `Revset`, I think it makes
more sense for `is_empty()` to be defined there. Maybe different
revset engines have different ways of implementing it. Even if they
don't, this is trivial to re-implement in each revset engine.
2023-03-13 07:20:35 -07:00
Martin von Zweigbergk
2d1b13b338 revset: make ToPredicateFn private, decouple public type from private
As the comment above `ToPredicateFn` says, it could be a private
type. This commit makes that happen by making the private `Revset`
implementations (`DifferenceRevset` etc.) instead implement an
internal revset type called `InternalRevset`. That type is what
extends `ToPredicateFn`, so the public type doesn't have to. The new
type will not need to implement the new functions I'm about to add to
the `Revset` trait.
2023-03-13 07:20:35 -07:00
Martin von Zweigbergk
9e6c139fa0 revset: create wrapper for current revset implementation
We don't want the public `Revset` interface to know about
`ToPredicateFn`. In order to hide it, I'm wrapping the internal type
in another type, so only the internal type can keep implementing
`ToPredicateFn`.
2023-03-13 07:20:35 -07:00
Martin von Zweigbergk
6c9cefb8a0 revset: make evaluate_revset() private and use it internally
I'd like to be able to change the return type of `evaluate_revset()`
to be an internal type. Since all external callers currently call the
function via `RevsetExpression::evaluate()`, it turns out it's easy to
make it private. To benefit from an internal type, we also need to
make the recursive calls be directly to the internal function.
2023-03-13 07:20:35 -07:00
Martin von Zweigbergk
ada48c6f71 revset: rename file() test for consistency
This should have been part of bbd6ef0c7b.
2023-03-13 07:20:35 -07:00
Martin von Zweigbergk
74ffe7f688 index: remove num_commits() from API 2023-03-12 22:08:31 -07:00
Martin von Zweigbergk
0a7de2540f tests: call num_commits() on specific implementation
This removes the last calls to `Index::num_commits()`.
2023-03-12 22:08:31 -07:00
Martin von Zweigbergk
52e4bee3fe index: remove stats() from API
The `stats()` function is specific to the default implementation, so
it shouldn't be part of the `Index` trait.
2023-03-12 22:08:31 -07:00