Commit graph

130 commits

Author SHA1 Message Date
Scott Taylor
5aa71d59a9 lib: replace MergedTreeId with MergedTree and Merge<TreeId>
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.
2025-11-08 14:06:58 +00:00
Brian Schroeder
7810926c35 index: make Index::is_ancestor fallible
This is part of a series of changes to make most methods on index traits
(i.e. `ChangeIdIndex`, `MutableIndex`, `ReadonlyIndex`, `Index`)
fallible. This will enable networked implementations of these traits,
which may produce I/O errors during operation. See #7825 for more
information.

- Introduced a few more instances of the existing anti-pattern, `TODO:
  indexing error shouldn't be a "BackendError"`. We're tracking this
  known issue in #7849.
- Converted `MutableRepo::merge_view` to return a `RepoLoaderError`
  instead of a `BackendError`. The only caller, `MutableRepo::merge`,
  already returns a `RepoLoaderError`.
- Added three "`fallible_`" iterator helpers to reduce the amount of
  noise at `is_ancestor` call sites due to the method now being
  fallible. Using these helpers seem to produce code that's a little
  more readable than using `process_results` from itertools. One
  consideration in this trade-off is that these helpers do not
  themselves return iterators: if we find that we need more support for
  fallible combinators mid-"chain" of iterator combinators, we might
  either want to use `process_results` only in those cases, or switch to
  use of `process_results` across the board (in lieu of these new
  helpers).
2025-10-28 13:47:44 +00:00
Brian Schroeder
b8fa9ecf9c index: make Index::has_id fallible
This is part of a series of changes to make most methods on index traits
(i.e. `ChangeIdIndex`, `MutableIndex`, `ReadonlyIndex`, `Index`)
fallible. This will enable networked implementations of these traits,
which may produce I/O errors during operation. See #7825 for more
information.
2025-10-25 18:05:13 +00:00
Brian Schroeder
c70f9b5b3f index: make ChangeIdIndex::shortest_unique_prefix_len fallible
This is part of a series of changes to make most methods on index traits
(i.e. `ChangeIdIndex`, `MutableIndex`, `ReadonlyIndex`, `Index`)
fallible. This will enable networked implementations of these traits,
which can produce I/O errors during operation. See #7825 for more
information.
2025-10-23 15:28:33 +00:00
Brian Schroeder
5468bb49d3 index: make ChangeIdIndex::resolve_prefix fallible
This is part of a series of changes to make most methods on index traits
(i.e. `ChangeIdIndex`, `MutableIndex`, `ReadonlyIndex`, `Index`)
fallible. This will enable networked implementations of these traits,
which can produce I/O errors during operation. See #7825 for more
information.
2025-10-23 15:28:33 +00:00
Yuya Nishihara
46d5555be4 cleanup: leverage trait upcasting, delete as_any*()
This patch also adds .downcast*() wrappers to prevent misuse of as &Any casting.
The compiler wouldn't help detect &Arc<T> as &Any, for example.

https://blog.rust-lang.org/2025/04/03/Rust-1.86.0/#trait-upcasting
2025-09-20 01:22:47 +00:00
Yuya Nishihara
bd2807fdbc store: downcast to implementation type by backend_impl()
It should be safer to restrict the type here.
2025-09-20 01:22:47 +00:00
Yuya Nishihara
fe7013b3dc commit: make is_empty() and parent_tree() query index first
This makes "jj log" in merge-heavy repos fast.
2025-08-21 09:38:38 +00:00
Yuya Nishihara
631bf709ec index: add generic interface to query changed paths in commit
Commit::is_empty() and ::parent_tree() will query index first to avoid merging
parent trees.

iirc, the Google backend has an index of changed paths, so I made the added
function return Result although the default index will never fail. I also
considered adding matcher argument, but I don't have any use case right now. I
think the Matcher API would be too abstract to construct a database query. Maybe
we should use Revset/FilesetExpression types for that purpose.
2025-08-21 09:38:38 +00:00
Yuya Nishihara
8999e08d2e index: add function to build changed-path index at certain operation 2025-08-15 11:46:49 +00:00
Yuya Nishihara
ad14c7bcc0 index: concatenate changed-path index on merge_in()
The logic is different from MutableCommitIndexSegment::merge_in() because we
need to deduplicate changed-path entries based on the commit entries.
2025-08-14 08:44:55 +00:00
Yuya Nishihara
a2155dcc95 index: squash changed-path segments before saving
The logic is the same as MutableCommitIndexSegment.
2025-08-14 08:44:55 +00:00
Yuya Nishihara
e31069cd3c index: index changed paths by add_commit()
Tests of the indexed contents will be added with the revset engine integration.
We don't have a public interface to get the indexed changed paths right now.
2025-08-11 11:50:39 +00:00
Yuya Nishihara
6bb26d8e73 index: include changed-path index in stats() 2025-08-11 11:50:39 +00:00
Yuya Nishihara
132d74a234 index: read/write changed-path index segments 2025-08-11 11:50:39 +00:00
Yuya Nishihara
3902d88b3e index: migrate operation link file to protobuf
I'm going to add changed-path index, and the operation link file will store a
list of segment files and a starting commit position. Suppose the link file is
small, we wouldn't need our own serialization format.

This patch adds new directory for proto-based operation link files. We could
reuse the existing directory, but that would make debugging a bit harder.
2025-08-11 11:50:39 +00:00
Martin von Zweigbergk
28562f1b10 tests: remove CommitGraphBuilder
The `CommitGraphBuilder` type doesn't seem to carry its weight
anymore.
2025-07-31 04:56:34 +00:00
Martin von Zweigbergk
ca6edfaab0 tests: add a helper for writing random commit with given parents 2025-07-31 04:56:34 +00:00
Scott Taylor
5ac6327b29 revset: add parents_range to Ancestors and Range
Using a range for this is consistent with the filter for parent count,
which also uses a `Range<u32>`. This could also be useful to implement
an `nth_parent()` revset in the future.
2025-07-28 22:16:04 +00:00
Austin Seipp
ba24140f1d cli, lib: move to Rust 2024 language edition
This applies a `cargo fmt` and fixes clippy lints to keep the build
properly working.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
2025-07-28 17:05:41 +00:00
Austin Seipp
2c2e974996 lib: fix 2024-incompatible usage of gen as a variable name
`gen` is now a reserved keyword; this also matches the surrounding use
of the word `generation` anyway, so IMO it's clearer.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
2025-07-28 17:05:41 +00:00
Yuya Nishihara
e8bce6f14b index: rename remaining "commit" index types as prep for changed-paths segments
- IndexPosition is renamed to GlobalCommitPosition because we have
  LocalCommitPosition, and GlobalCommitPosition is no longer a public type.
- Private types such as ParentIndexPosition aren't renamed. I'll probably split
  commit index modules instead.
- ReadonlyIndexLoadError isn't renamed because I'm not sure if we'll add a new
  error type dedicated for new changed-paths index.
- IndexLevelStats is renamed, but IndexStats isn't because I'll probably add
  stats of changed-paths index.
2025-07-21 02:45:58 +00:00
Yuya Nishihara
e4f0942f26 index: replace external users of CompositeIndex 2025-07-10 12:40:13 +00:00
Yuya Nishihara
f1b29510d3 object_id: rename HexPrefix::new() to ::try_from_hex() for consistency 2025-07-02 01:56:40 +00:00
Yuya Nishihara
02722eae54 view: port bookmark/tag name types to RefName/RemoteName
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.
2025-03-26 11:07:06 +00:00
Yuya Nishihara
cc8a80c548 ref_name: move RemoteRefSymbol types from refs module 2025-03-26 11:07:06 +00:00
Ilya Grigoriev
acaedc3382 cleanup: enable unused_trait_names clippy lint and run clippy --fix 2025-03-16 00:35:56 +00:00
Yuya Nishihara
ae8e6e8e8e view: port remote_bookmark accessors to RemoteRefSymbol 2025-02-26 03:17:45 +00:00
Yuya Nishihara
cff73841ed repo: remove &UserSettings argument from new/rewrite_commit(), use self.settings 2024-12-31 10:51:57 +09:00
Yuya Nishihara
14b52205fb repo: remove &UserSettings argument from start_transaction(), use self.settings 2024-12-31 10:51:57 +09:00
Martin von Zweigbergk
de6da1a088 transaction: propagate errors from commit() 2024-11-13 23:05:24 -08:00
Yuya Nishihara
d4786a3256 testutils: move load_repo_at_head() to TestEnvironment
It will depend on the TestBackendData mapping.
2024-11-02 08:39:02 +09:00
Samuel Tardieu
3f2ef2ee04 style: add semicolon at the end of expressions used as statements 2024-10-04 22:29:13 +02:00
Martin von Zweigbergk
1aa2aec141 bookmarks: update some leftover uses of the word "branch" 2024-09-11 19:19:31 -07:00
Philip Metzger
d9c68e08b1 everything: Rename branches to bookmarks
Jujutsu's branches do not behave like Git branches, which is a major
hurdle for people adopting it from Git. They rather behave like
Mercurial's (hg) bookmarks. 

We've had multiple discussions about it in the last ~1.5 years about this rename in the Discord, 
where multiple people agreed that this _false_ familiarity does not help anyone. Initially we were 
reluctant to do it but overtime, more and more users agreed that `bookmark` was a better for name 
the current mechanism. This may be hard break for current `jj branch` users, but it will immensly 
help Jujutsu's future, by defining it as our first own term. The `[experimental-moving-branches]` 
config option is currently left alone, to force not another large config update for
users, since the last time this happened was when `jj log -T show` was removed, which immediately 
resulted in breaking users and introduced soft deprecations.

This name change will also make it easier to introduce Topics (#3402) as _topological branches_ 
with a easier model. 

This was mostly done via LSP, ripgrep and sed and a whole bunch of manual changes either from
me being lazy or thankfully pointed out by reviewers.
2024-09-11 18:54:45 +02:00
Martin von Zweigbergk
19f383ffdd tests: avoid ReadonlyRepo::repo_path() 2024-09-07 12:20:02 -07:00
Martin von Zweigbergk
8d090628c3 transaction: rename mut_repo() to idiomatic repo_mut()
We had both `repo()` and `mut_repo()` on `Transaction` and I think it
was easy to get confused and think that the former returned a
`&ReadonlyRepo` but both of them actually return a reference to
`MutableRepo` (the latter obviously returns a mutable reference). I
hope that renaming to the more idiomatic `repo_mut()` will help
clarify.

We could instead have renamed them to `mut_repo()` and
`mut_repo_mut()` but that seemed unnecessarily long. It would better
match the `mut_repo` variables we typically use, though.
2024-09-07 10:51:43 -07:00
Matt Kulukundis
8ead72e99f formatting only: switch to Item level import ganularity 2024-08-22 14:52:54 -04:00
Martin von Zweigbergk
bfa0573cab repo/workspace: drop support for old repo formats
It's been more than 6 months since we added support for dynamically
selecting the working copy implementation. This patch drops support
for selecting the default implementation of that and other stores.
2024-06-11 22:03:20 +09:00
Yuya Nishihara
243675b793 index: turn CompositeIndex into transparent reference type
This helps to eliminate higher-ranked trait bounds from RevWalkRevset and
RevWalk combinators to be added. Since &CompositeIndex is now a real reference,
it can be passed to functions as index: &T.
2024-03-11 17:24:10 +09:00
Yuya Nishihara
f5eb172769 tests: remove last use of walk_revs() from integration tests 2024-03-08 10:07:40 +09:00
Yuya Nishihara
3c7aa75b9b index: switch to persistent change id index
The shortest change id prefix will become a few digits longer, but I think
that's acceptable. Entries included in the "revsets.short-prefixes" set are
unaffected.

The reachable set is calculated eagerly, but this is still faster as we no
longer need to sort the reachable entries by change id. The lazy version will
save another ~100ms in mid-size repos.

"jj log" without working copy snapshot:
```
% hyperfine --sort command --warmup 3 --runs 20 -L bin jj-0,jj-1,jj-2 \
  -s "target/release-with-debug/{bin} -R ~/mirrors/linux debug reindex" \
  "target/release-with-debug/{bin} -R ~/mirrors/linux \
   --ignore-working-copy log -r.. -l100 --config-toml='revsets.short-prefixes=\"\"'"
Benchmark 1: target/release-with-debug/jj-0 -R ~/mirrors/linux --ignore-working-copy log -r.. -l100 --config-toml='revsets.short-prefixes=""'
  Time (mean ± σ):     353.6 ms ±  11.9 ms    [User: 266.7 ms, System: 87.0 ms]
  Range (min … max):   329.0 ms … 365.6 ms    20 runs

Benchmark 2: target/release-with-debug/jj-1 -R ~/mirrors/linux --ignore-working-copy log -r.. -l100 --config-toml='revsets.short-prefixes=""'
  Time (mean ± σ):     271.3 ms ±   9.9 ms    [User: 183.8 ms, System: 87.7 ms]
  Range (min … max):   250.5 ms … 282.7 ms    20 runs

Relative speed comparison
        1.99 ±  0.16  target/release-with-debug/jj-0 -R ~/mirrors/linux --ignore-working-copy log -r.. -l100 --config-toml='revsets.short-prefixes=""'
        1.53 ±  0.12  target/release-with-debug/jj-1 -R ~/mirrors/linux --ignore-working-copy log -r.. -l100 --config-toml='revsets.short-prefixes=""'
```

"jj status" with working copy snapshot (watchman enabled):
```
% hyperfine --sort command --warmup 3 --runs 20 -L bin jj-0,jj-1,jj-2 \
  -s "target/release-with-debug/{bin} -R ~/mirrors/linux debug reindex" \
  "target/release-with-debug/{bin} -R ~/mirrors/linux \
   status --config-toml='revsets.short-prefixes=\"\"'"
Benchmark 1: target/release-with-debug/jj-0 -R ~/mirrors/linux status --config-toml='revsets.short-prefixes=""'
  Time (mean ± σ):     396.6 ms ±  10.1 ms    [User: 300.7 ms, System: 94.0 ms]
  Range (min … max):   373.6 ms … 408.0 ms    20 runs

Benchmark 2: target/release-with-debug/jj-1 -R ~/mirrors/linux status --config-toml='revsets.short-prefixes=""'
  Time (mean ± σ):     318.6 ms ±  12.6 ms    [User: 219.1 ms, System: 94.1 ms]
  Range (min … max):   294.2 ms … 333.0 ms    20 runs

Relative speed comparison
        1.85 ±  0.14  target/release-with-debug/jj-0 -R ~/mirrors/linux status --config-toml='revsets.short-prefixes=""'
        1.48 ±  0.12  target/release-with-debug/jj-1 -R ~/mirrors/linux status --config-toml='revsets.short-prefixes=""'
```
2024-02-18 09:44:57 +09:00
Yuya Nishihara
8cdf6d752c index: move change ids to sstable, build change-id-to-pos lookup table
This basically means that the change ids are interned. We'll implement binary
search over the sorted change ids table. The table could be sorted differently
for better cache locality, but it is in lexicographical order for simplicity.
With my testing, the cost of the id lookup isn't dominant.

Unlike the parent entries, the size of the per-id overflow items isn't saved.
That's s because the number of the same-change-id commits is either 1 or many.
It doesn't make sense to allocate 8 bytes for each change id. Instead, we'll
pay extra indirection cost to determine the size.
2024-02-18 09:44:57 +09:00
Yuya Nishihara
e2c8a8fabd index: fix change id resolution test to not depend on deterministic order
Since IdIndex sorts the entries by using .sort_unstable_by_key(), the order of
the same-key elements is undefined. Perhaps, it's stable for short arrays, and
the test passes because of that.
2024-02-14 23:22:23 +09:00
Yuya Nishihara
b0e8e2a1af index: move segment files to sub directory, add version number
I'm going to introduce breaking changes in index format. Some of them will
affect the file size, so version number or signature won't be needed. However,
I think it's safer to detect the format change as early as possible.

I have no idea if embedded version number is the best way. Because segment
files are looked up through the operation links, the version number could be
stored there and/or the "segments" directory could be versioned. If we want to
support multiple format versions and clients, it might be better to split the
tables into data chunks (e.g. graph entries, commit id table, change id table),
and add per-chunk version/type tag. I choose the per-file version just because
it's simple and would be non-controversial.

As I'm going to introduce format change pretty soon, this patch doesn't
implement data migration. The existing index files will be deleted and new
files will be created from scratch.

Planned index format changes include:
 1. remove unused "flags" field
 2. inline commit parents up to two
 3. add sorted change ids table
2024-02-12 19:38:36 +09:00
Yuya Nishihara
b7eb551cf7 index: fix reindexing to scan all referenced commits such as hidden remote refs
Since hidden commits can be looked up by remote_branches() revset for example,
reindexing should traverse ancestors from all named refs in addition to the
visible heads.
2024-01-12 12:53:16 +09:00
Yuya Nishihara
e5286aed08 index: move lifetimed change_id_index() to MutableIndex, rename 'static version
change_id_index() is only used by Readonly/MutableRepo, so we don't need an
abstraction at Index. evaluate_revset() is somewhat similar, but the callers
rely on &dyn Repo.
2024-01-09 10:38:00 +09:00
Martin von Zweigbergk
c98b0d76af index: move Revset::change_id_index() to Index
We current have `Revset::change_id_index()` for creating a
`ChangeIdIndex` for a given revset. I think it will be hard to make it
performant for general revsets, especially in very large repos and
with custom index implementations, like the one we have at Google. If
we instead restrict it to including all ancestors of a set of heads, I
think it will be much easier to implement. We only use
`Revset::change_id_index()` with revsets including all visible commits
today, so we won't lose any current functionality by making it more
restricted.
2024-01-08 06:06:47 -08:00
Martin von Zweigbergk
2f4594540a tests: move ChangeIdIndex test from test_revset to test_index 2024-01-08 06:06:47 -08:00
Yuya Nishihara
fa5e40719c object_id: extract ObjectId trait and macros to separate module
I'm going to add a prefix resolution method to OpStore, but OpStore is
unrelated to the index. I think ObjectId, HexPrefix, and PrefixResolution can
be extracted to this module.
2024-01-05 10:20:57 +09:00