Commit graph

2045 commits

Author SHA1 Message Date
Yuya Nishihara
7a44e590dc lock: remove byteorder dependency from tests, use fs helper functions
This is the last use of Read/WriteBytesExt. The byteorder crate is great, but
we don't need an abstraction of endianness. Let's simply use the std functions.
2023-12-23 00:14:17 +09:00
Yuya Nishihara
9de6273e10 index, stacked_table: inline read_u32::<LittleEndian>()
There aren't many callers of ReadBytesExt::read_u32().
2023-12-23 00:14:17 +09:00
Yuya Nishihara
21c22be96e stacked_table: use u32::from_le_bytes() to reinterpret bytes as integer
Apparently, I forgot to update this in fb06e89649.
2023-12-23 00:14:17 +09:00
Yuya Nishihara
6f5096e266 index, stacked_table: use u32::try_from() instead of numeric cast
These .unwrap()s wouldn't be compiled out, but I don't think they would
have measurable impact. Let's use the safer method.
2023-12-22 09:03:50 +09:00
Yuya Nishihara
9ec89bcf86 index, stacked_table: use u32::to_le_bytes() to reinterpret as bytes 2023-12-22 09:03:50 +09:00
Yuya Nishihara
392539fa29 index, stacked_table: simply extend Vec<u8> to not use .write_all()
I'm going to remove use of .write_u32() there. It's not super important, but
fewer .unwrap()s, the code looks slightly better.
2023-12-22 09:03:50 +09:00
Yuya Nishihara
fb06e89649 index: use u32::from_le_bytes() to reinterpret bytes as integer
It's less abstract than going through io::Read, so is probably easier for
compiler to optimize out. I also feel it's a bit more readable.
2023-12-22 09:03:50 +09:00
Yuya Nishihara
38ce914321 index: reindex on content-related I/O errors
If read_exact() or read_u32() reached to EOF, the index file should be
considered corrupted. File not found error is also treated as data corruption
because an invalid file name could be read from the child segment file. It
can't handle special file names like "..", though.
2023-12-21 08:05:30 +09:00
Yuya Nishihara
e98104d6f0 index: add file name to both io/corrupt errors, combine these variants
Index file name also applies to io::Error. New error type reuses io::Error to
represent data corruption. We could add an inner Corrupt|Io enum instead, but
we'll need to remap some io::Error variants (e.g. UnexpectedEof) to Corrupt
anyway.
2023-12-21 08:05:30 +09:00
Yuya Nishihara
88f3085bb1 index: extract function that opens file and loads index segments 2023-12-21 08:05:30 +09:00
Yuya Nishihara
eccb9b7a44 index: propagate index load errors from DefaultIndexStore 2023-12-19 07:41:57 +09:00
Yuya Nishihara
dd8e686127 index: don't reload parent files after saving new segment file
This should be cheaper, and more importantly, we no longer need to propagate
ReadonlyIndexLoadError to the caller.
2023-12-19 07:41:57 +09:00
Yuya Nishihara
fb07749291 index: split load function into header and local parts as well 2023-12-19 07:41:57 +09:00
Yuya Nishihara
616a8c7f54 index: split serialization function into header and local parts
The idea is that we don't have to reload parent files as we already have the
chain of the parent segments. The resulting readonly index will be constructed
from the loaded parent segments + local entries blob.
2023-12-19 07:41:57 +09:00
Yuya Nishihara
31b6e93c6e index: move IndexLoadError to "readonly" module, rename accordingly
I thought IndexLoadError and DefaultIndexStoreError would represent "load" and
"store" failures respectively, but they aren't. Actually, DefaultIndexStoreError
is the store-level error, and IndexLoadError should be wrapped in it.
2023-12-19 07:41:57 +09:00
Yuya Nishihara
b5de16007e index: add stub IndexReadError type
This is needed to remove .unwrap()s from DefaultIndexStore.
2023-12-19 07:41:57 +09:00
Yuya Nishihara
d49b079494 index: update file format comment about ReadonlyIndexSegment
Also made it a doc comment. I think 4-byte alignment is a nice property,
so added note about that.
2023-12-19 07:41:34 +09:00
Yuya Nishihara
8909647d86 index: pass base directory path by reference 2023-12-18 08:49:21 +09:00
Yuya Nishihara
b733d52557 index: split DefaultIndexStoreError::Io variant, extract save helper
Since OpStoreError can also include io::Error, it doesn't make much sense to
have Io variant at this level. Let's split it to context-specific errors, and
extract helper method that maps io::Error.
2023-12-18 08:49:21 +09:00
Yuya Nishihara
bf4a4e70b1 index: use DefaultMutableIndex wrapper when reconstructing missing index
This allows us to extract helper method that writes index file and associates
it with the operation.
2023-12-18 08:49:21 +09:00
Yuya Nishihara
50164bb36f index: have IndexWriteError carry opaque error type instead of string
I'm going to remove some .unwrap()s from DefaultIndexStore, and the inner
error type will be consolidated to DefaultIndexStoreError.
2023-12-18 08:49:21 +09:00
Yuya Nishihara
87a8238bee git: turn git.auto-local-branch off by default
As far as I can see in the chat, there's no objection to changing the default,
and git.auto-local-branch = false is generally preferred.

docs/branches.md isn't updated as it would otherwise conflict with #2625. I
think the "Remotes" section will need a non-trivial rewrite.

#1136, #1862
2023-12-17 08:30:24 +09:00
Yuya Nishihara
ac99145a28 working_copy: drop open file instance from PersistError
For the same reason as the file_util change.
2023-12-17 08:20:07 +09:00
Yuya Nishihara
c6df0ba4c3 file_util: don't try to overwrite existing content-addressed file on Windows
The doc says persist() replaces the destination file as rename() would do
on Unix. persist_noclobber() doesn't, and is probably more reliable on Windows.
I don't know if persist() is completely atomic on Windows, but if it isn't, it
might be the source of the "permission denied" error under highly contended
situation.

https://docs.rs/tempfile/latest/tempfile/struct.NamedTempFile.html#method.persist
https://github.com/Stebalien/tempfile/blob/v3.8.0/src/file/imp/windows.rs#L77

We could use persist_noclobber() on all platforms, but it's more involved on
Unix.

https://github.com/Stebalien/tempfile/blob/v3.8.0/src/file/imp/unix.rs#L107
2023-12-17 08:20:07 +09:00
Yuya Nishihara
dd325c089c file_util: drop open file instance from PersistError
PersistError is basically a pair of io::Error and NamedTempFile instance. It's
unlikely that we would want to propagate the open file instance to the CLI
error handler, leaving the temporary file alive.
2023-12-17 08:20:07 +09:00
Yuya Nishihara
4d91e4c196 revset: simplify type constraints on combination iterators
Just a minor cleanup to remove lifetime parameter from the types. I tried to
reimplement them by using itertools, but I couldn't find a simple way to
encode short-circuiting at the end of either left or right iterator.
2023-12-16 07:50:04 +09:00
Yuya Nishihara
6d59156858 revset: parameterize candidates set of FilterRevset as well 2023-12-16 07:50:04 +09:00
Yuya Nishihara
a36368bb88 revset: make revset combinators generic over set types, merge UnionPredicate
UnionRevset and UnionPredicate are conceptually the same. Let's unify them.
2023-12-16 07:50:04 +09:00
Yuya Nishihara
af6047a655 lib: forbid unsafe_code at all 2023-12-15 16:10:28 +09:00
Yuya Nishihara
9990c41a90 repo: remove unsafe lifetime hack from change_id_index() 2023-12-15 16:10:28 +09:00
Yuya Nishihara
d9e8297059 index: add 'static version of evaluate_revset() to ReadonlyIndex
We'll probably need a better abstraction, but a separate method is good
enough to remove unsafe code from ReadonlyRepo.

I'm not sure if this is feasible for the other backends, but I guess there
would be less lifetimed variables than DefaultReadonlyIndex.
2023-12-15 16:10:28 +09:00
Yuya Nishihara
2ba50c76c7 revset: abstract evaluated RevsetImpl over owned/borrowed index types 2023-12-15 16:10:28 +09:00
Yuya Nishihara
72d9cd019b index: extract as_composite() to trait method
The revset engine will accept abstract AsCompositeIndex type, and the
evaluated revset can be 'static if the index is behind Arc<T>.
2023-12-15 16:10:28 +09:00
Yuya Nishihara
8fdf9db6e0 revset: remove 'index lifetime from InternalRevset 2023-12-15 14:58:12 +09:00
Yuya Nishihara
c426d34c11 revset: pass in index to PurePredicateFn as an argument to make it 'static 2023-12-15 14:58:12 +09:00
Yuya Nishihara
71070e85d7 revset: add helper that coerces closure to PurePredicateFn
Also renamed the boxed version to discriminate it from the cast helper.
2023-12-15 14:58:12 +09:00
Yuya Nishihara
a9a7de4a5e revset: store RevWalk factory function in RevWalkRevset
The returned iterator is boxed by caller due to the limitation of the type
system. There's a workaround, but it's super ugly.

https://users.rust-lang.org/t/hrtb-on-multiple-generics/34255/3
2023-12-15 14:58:12 +09:00
Yuya Nishihara
575d3dc7bf revset: store IndexPosition in EagerRevset to drop 'index lifetime
This adds overhead to re-look up IndexEntry, but I don't think that would
have significant impact on performance.
2023-12-15 14:58:12 +09:00
Yuya Nishihara
261bf848a9 revset: pass in index to InternalRevset as an argument
The idea is that InternalRevset will store a 'static boilerplate function that
borrows an 'index passed by function argument. This way, we can abstract the
index type over Arc<T> and &T without introducing too much generics.
2023-12-15 14:58:12 +09:00
Yuya Nishihara
e332d39375 revset: extract inner method that constructs IndexEntry iterator 2023-12-15 14:58:12 +09:00
Yuya Nishihara
b8f60c4dd6 cargo: bump gix to 0.56.0
I don't know why the dependabot didn't catch this, but there are things to
fix manually. EntryMode was changed to a u16 wrapper, and the enum was renamed
to EntryKind. Other than that, I don't find anything breaking our codebase.
2023-12-15 14:17:02 +09:00
Yuya Nishihara
95a0cceb97 index: use loaded readonly data without splitting into vecs
Since lookup data isn't typically small, .split_off() can take a few
milliseconds to memcpy().
2023-12-14 08:43:50 +09:00
Yuya Nishihara
5121e1f4e9 index: move IndexSegment trait to "composite" module
Perhaps, this is the most controversial part. It could be moved to new
"segment" module (or something like "common"), but I think IndexSegment can be
considered a trait that enables the CompositeIndex abstraction.
2023-12-14 08:43:40 +09:00
Yuya Nishihara
b89ae7c0b5 index: use IndexEntry::position() instead of direct field access 2023-12-14 08:43:40 +09:00
Yuya Nishihara
9fb0f00f2d index: add IndexEntry constructor instead of pub(super)-ing fields 2023-12-14 08:43:40 +09:00
Yuya Nishihara
771f447d99 index: split IndexEntry and related types to "entry" module
Added pub(super) or pub where needed. I won't implement accessor methods on
IndexPositionByGeneration and IndexPosition as they are purely value types,
and protecting the inner values wouldn't make sense.
2023-12-14 08:43:40 +09:00
Martin von Zweigbergk
60fae3114e transaction: take description at end instead of start
It seems better to have the caller pass the transaction description
when we finish the transaction than when we start it. That way we have
all the information we want to include more readily available.
2023-12-13 08:12:49 -08:00
Ilya Grigoriev
316ab8efb8 rewrite.rs: refactor new_parents to depend only on parent_mapping
Previously, the function relied on both the `self.parent_mapping` and
`self.rebased`. If `(A,B)` was in `parent_mapping` and `(B,C)` was in `rebased`,
`new_parents` would map `A` to `C`.

Now, `self.rebased` is ignored by `new_parents`. In the same situation,
DescendantRebaser is changed so that both `(A,B)` and `(B,C)` are in
`parent_mapping` before. `new_parents` now applies `parent_mapping` repeatedly,
and will map `A` to `C` in this situation.

## Cons

- The semantics are changed; `new_parents` now panics if `self.parent_mapping`
  contain cycles. AFAICT, such cycles never happen in `jj` anyway, except for
one test that I had to fix. I think it's a sensible restriction to live with;
if you do want to swap children of two commits, you can call
`rebase_descendants` twice.

## Pros

- I find the new logic much easier to reason about. I plan to extract it into a
function, to be used in refactors for `jj rebase -r` and `jj new --after`. It
will make it much easier to have a correct implementation of `jj rebase -r
--after`, even when rebasing onto a descendant.

- The de-duplication is no longer O(n^2). I tried to keep the common case fast.

## Alternatives

- We could make `jj rebase` and `jj new` use a separate function with the
algorithm shown here, without changing DescendantRebaser. I believe that the new
algorithm makes DescendatRebaser easier to understand, though, and it feels more
elegant to reduce code duplication.

- The de-duplication optimization here is independent of other changes, and
could be used on its own.
2023-12-12 19:35:51 -08:00
Yuya Nishihara
2abbb637e3 index: add wrapper functions to DefaultReadonlyIndex to remove pub(super) field 2023-12-13 08:09:48 +09:00
Yuya Nishihara
c0a12a7cbc index: add methods that provides commit/change_id_length
We could add Layout struct holding these parameters, but I don't think that's
needed just for two parameters.
2023-12-13 08:09:48 +09:00