Commit graph

2401 commits

Author SHA1 Message Date
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
Yuya Nishihara
3831ad423c index: use as_composite().num_commits() instead of direct field access 2023-12-13 08:09:48 +09:00
Yuya Nishihara
30984b1505 index: use name() instead of direct field access 2023-12-13 08:09:48 +09:00
Yuya Nishihara
e5c8252fb4 index: use segment_parent_file() instead of direct field access 2023-12-13 08:09:48 +09:00
Yuya Nishihara
402e36bab7 index: split readonly index types to "readonly" module
Added pub(super) where needed. There are a few pub(super) fields that look
suspicious, which will be fixed by the subsequent patches.
2023-12-13 08:09:48 +09:00
Yuya Nishihara
fbec16b49f index: add wrapper functions to DefaultMutableIndex to remove pub(super) field
into_segment() could be added instead of save_in(), but I decided to wrap
save_in(). save_in() may squash ancestor files, so it could be considered an
index-level operation.
2023-12-13 08:09:48 +09:00
Yuya Nishihara
5aeeb5f723 index: split mutable index types to "mutable" module
Added pub(super) where needed or makes sense.
2023-12-13 08:09:48 +09:00
Yuya Nishihara
ab2742f2c9 index: split RevWalk types to "rev_walk" module
Added pub(super) where needed.
2023-12-12 08:07:52 +09:00
Yuya Nishihara
caa1b99c24 index: add CompositeIndex constructor instead of pub(super)-ing field
This wouldn't matter, but seemed slightly better.
2023-12-12 08:07:52 +09:00
Yuya Nishihara
679518fdf2 index: split CompositeIndex and stats types to "composite" module
Added pub(super) where needed or makes sense.
2023-12-12 08:07:52 +09:00
Yuya Nishihara
2423558e68 index: split DefaultIndexStore and Load/StoreError types to "store" module
IndexLoadError isn't store-specific, but I think it's better to put I/O
stuff in the store module.
2023-12-12 08:07:52 +09:00
Yuya Nishihara
cdcd465c79 index: move default_index_store.rs to sub directory named default_index
default_index_store.rs is relatively big, and it contains types and impls in
arbitrary order. Let's split them into sub modules. After everything moved,
mod.rs will only contain tests.
2023-12-12 08:07:52 +09:00
Yuya Nishihara
f86b338681 revset: inline walk_ancestors() 2023-12-11 09:14:03 +09:00
Yuya Nishihara
cd0b24ef14 revset: inline walk_children()
There's only one caller, and we have common code at the call site.
2023-12-11 09:14:03 +09:00
Yuya Nishihara
d28bd8fa0f revset: inline collect_dag_range() 2023-12-11 09:14:03 +09:00
Yuya Nishihara
73fb922517 index: reimplement collect_dag_range() of revset engine as iterator
I'm going to remove 'index lifetime from InternalRevset so Revset<'static>
can be easily constructed from DefaultReadonlyIndex. As the first step, this
series removes some lifetime complexity from EvaluationContext methods.

We don't need an descendant iterator API, but it helps to add separate function
to collect into HashSet<IndexPosition> instead of returning a pair of
ordered vec and set.
2023-12-11 09:14:03 +09:00
Yuya Nishihara
cbbe38ba7b index: rename MutableIndexImpl to MutableIndexSegment 2023-12-10 11:03:07 +09:00
Yuya Nishihara
c94e1de6d2 index: add DefaultMutableIndex wrapper, move Index impls to it
The wrapper type isn't needed for the mutable layer, but this mirrors the
readonly type structure. Test cases are also migrated to be using the index
wrapper so long as we don't have to care for the nesting of the segment files.
2023-12-10 11:03:07 +09:00
Yuya Nishihara
ce312ae288 index: duplicate add_commit() to MutableIndexImpl 2023-12-10 11:03:07 +09:00
Yuya Nishihara
e0206a82f2 index: extract merge_in() function that works on segment types
Prepares for splitting MutableIndexImpl into segment and index wrapper types.
2023-12-10 11:03:07 +09:00
Yuya Nishihara
a110ec6d95 cli: print failed git export reason for each ref
Not all reasons are actionable, but we print hint in common cryptic cases.
2023-12-09 23:37:00 +09:00
Yuya Nishihara
990edcefc9 index: impl Index for DefaultReadonlyIndex instead of ReadonlyIndexSegment
The idea is that the ReadonlyIndexSegment is a sub component of the index. The
Index trait could be implemented for any Segment type, but we don't need a
public interface to access sub segment as an index.
2023-12-09 15:18:36 +09:00
Yuya Nishihara
1cbd2ddb4b index: rename ReadonlyIndexImpl to ReadonlyIndexSegment
I'm going to split the internal Segment types and the public Index types
in order to clarify the layering concept. The public Index types will be
wrappers like DefaultReadonlyIndex.

Strictly speaking, ReadonlyIndexImpl is a segment + parent pointer pair,
but I think calling it a segment is pretty okay. It could be called a
ReadonlyIndexFile, but "File" can't apply to the mutable part.
2023-12-09 15:18:36 +09:00
Yuya Nishihara
172043e968 index: make ReadonlyIndexImpl private
There are no external callers.
2023-12-09 15:18:36 +09:00
Yuya Nishihara
6c57ba7f21 index: rename ReadonlyIndexWrapper to DefaultReadonlyIndex
This matches the store naming: impl IndexStore for DefaultIndexStore. I also
added minimal doc comment and Debug.
2023-12-09 15:18:36 +09:00