Commit graph

44 commits

Author SHA1 Message Date
Martin von Zweigbergk
61ffa66fb5 view: move merge_views() onto View 2021-06-05 14:08:04 -07:00
Martin von Zweigbergk
ac2530637a view: merge ReadonlyView and MutableView into a single View
The two types have become very similar so it doesn't seem that there's
any point in having two types. We should probably do the same with
`ReadonlyEvolution` and `MutableEvolution`.
2021-06-05 14:08:04 -07:00
Martin von Zweigbergk
70b99c960e transaction: make commit() return resulting ReadonlyRepo
I've wanted the API to look like this for a while. It seems like a
good API to me. It means that the caller won't have to reload the repo
after committing. The cost seems relatively small. It involves copying
potentially a lot of data in memory (at least the View object), but it
shouldn't involve reading from disk or any other processing. To reduce
the amount of data to copy, it may be worth switching to persistent
data types. I've also wanted to do that for the copying we do when
start a transaction.

I couldn't measure any slowdown caused by this change.
2021-05-08 13:50:59 -07:00
Martin von Zweigbergk
1ebdd4ecf0 MutableRepo: use index when enforcing view invariants
We can now finally use the commit index for filtering out ancestors
from the sets of heads.

I haven't timed the change from most of the recent work on
performance, but I did a measurement after this commit. I modified a
commit in the git.git repo's "what's cooking" branch (because that's
linear). Then I ran `jj evolve` so the 100 commits after it would get
evolved. That took ~700ms. `git rebase` of the same 100 commits took
~6s.

I also compared `jj op undo` of that `jj evolve` operation. With this
patch, that was sped up from ~6.8s to ~125ms.
2021-03-15 16:35:45 -07:00
Martin von Zweigbergk
2c92fca75a MutableView: don't require whole Commit when CommitId is enough 2021-03-15 15:36:03 -07:00
Martin von Zweigbergk
b4b1de3ddc view: let MutableRepo enforce view invariants
`MutableRepo` has more information needed for taking fast-paths, and
it will have to make the same decision for doing incremental updates
of the evolution state anyway.
2021-03-15 15:17:36 -07:00
Martin von Zweigbergk
b9fe944e76 view: remove unnecessary removing of parents in add_head()
We call `enforce_invariants()` right after removing the parent
commits, and that will remove parents anyway.
2021-03-15 15:06:14 -07:00
Martin von Zweigbergk
5631e85502 view: don't enforce invariants in merge_views()
We now only call the function from `MutableRepo::merge()`. There we
pass the result to `MutableView::set_view()`, which already enforces
the invariants.
2021-03-14 11:07:34 -07:00
Martin von Zweigbergk
8048d9641e commands: rewrite jj op undo using new MutableRepo::merge() 2021-03-14 10:57:57 -07:00
Martin von Zweigbergk
4b8484e561 rustfmt: configure to group imports 2021-03-14 10:46:25 -07:00
Martin von Zweigbergk
ac9fb1832d OpHeadsStore: move logic for merging repos to MutableRepo
This adds `MutableRepo::merge()`, which applies the difference between
two `ReadonRepo`s to itself. That results in much simpler code than
the current code in `merge_op_heads()`. It also lets us write `undo`
using the new function. Finally -- and this is the actual reason I did
it now -- it prepares for using the index when enforcing view
invariants.
2021-03-14 10:43:39 -07:00
Martin von Zweigbergk
7ea0c6a868 View: move op_id/base_op_id to Repo
This is yet another step towards making the `View` types
simpler. Perhaps we eventually won't need to wrap the types returned
from the `OpStore` at all.
2021-03-14 00:25:02 -08:00
Martin von Zweigbergk
c1de8b0f3a View: move creation of Operation to Transaction
This continues the work to make the `View` types be only about the
state of the current view and not about operations in general (which
has been moved out `OpStore` and qOpHeadsStore`).
2021-03-14 00:16:21 -08:00
Martin von Zweigbergk
f79874d612 view: let repo get current operation from OpHeadsStore and pass in
This makes the View types a lot simpler.
2021-03-11 22:23:02 -08:00
Martin von Zweigbergk
82a3ff6ef8 repo: make OpHeadsStore accessible directly on ReadonlyRepo
We can now get rid of `MutableView::update_op_heads()`.
2021-03-10 23:27:36 -08:00
Martin von Zweigbergk
212dd35d01 view: let repo create OpHeadsStore and pass in to view 2021-03-10 23:14:00 -08:00
Martin von Zweigbergk
ec07104126 view: move creation of initial operation to OpHeadsStore
This is a step towards getting rid of
`MutableView::update_op_heads()`.
2021-03-10 22:57:59 -08:00
Martin von Zweigbergk
2590e127f7 view: move get_single_op_head() onto OpHeadsStore 2021-03-10 21:59:32 -08:00
Martin von Zweigbergk
b4d4cd143a view: move locking of .jj/view/op_heads/ to OpHeadsStore 2021-03-10 21:51:08 -08:00
Martin von Zweigbergk
4bd121dab5 view: split out separate type for keeping track of op heads 2021-03-10 21:34:11 -08:00
Martin von Zweigbergk
2955bc4a29 repo: let repo types directly have an OpStore
I'd like to make `ReadonlyView` and `MutableView` focused on just the
state of the view (i.e. the set of heads, git refs, etc.). The
responsibility for managing the `.jj/view/op_heads/` directory should
be moved out of it. This prepares for that.
2021-03-10 20:55:56 -08:00
Martin von Zweigbergk
48d7903925 repo: simplify and clarify name of base_op_head_id() functions 2021-03-10 15:39:15 -08:00
Martin von Zweigbergk
9ee521d9d3 transaction: fix (mostly harmless) race where index can get re-calculated 2021-03-10 15:22:03 -08:00
Martin von Zweigbergk
47a7cf7101 view: extract function for updating operation heads
This will be used to address the race in `Transaction::commit()`.
2021-03-10 15:17:54 -08:00
Martin von Zweigbergk
fc73ef8d6e view: delete an incorrect comment about a race
Unlike in `Transaction::commit()`, in the `view` module, we actually
don't update the `.jj/view/op_heads/` directory until after we've
recorded the index associated with the operation, so there's no race
there.
2021-03-10 14:30:27 -08:00
Martin von Zweigbergk
a715fd0ae7 view: drop stale comment about resolving concurrent operations
The comment was from the time when we resolved divergent operations at
write time.
2021-03-08 23:18:26 -08:00
Martin von Zweigbergk
e6aa2402a6 view: drop redundant filtering of ancestors of public heads
I added `enforce_invariants()` in 1f593a4193 and then forgot to use
it in 4db3d8d3a6.
2021-03-08 23:18:26 -08:00
Martin von Zweigbergk
f755c3f740 cleanup: access integer types' MAX constants directly on the type
Using `std::u32::MAX` is deprecated.
2021-03-08 23:18:17 -08:00
Martin von Zweigbergk
1e623bd019 index: update in memory and on disk while resolving operation conflicts
Updating the index on disk means that reader won't have to calculate
the state. Updating it in memory means that we can take advantage of
it while resolving conflicts. We will do that soon.
2021-03-06 23:30:03 -08:00
Martin von Zweigbergk
0a4ef1030f repo: add support for loading at given operation without loading head op first
The only way to load the repo at a current operation (as with
`--at-op`) is currently to first load it at the head operation and
then call `reload()` on the repo. This patch makes it so we can load
the repo directly at the requested operation.
2021-03-06 09:52:10 -08:00
Martin von Zweigbergk
5a32118af1 repo: move creation of OpStore out of View
We want to support loading the repo at a specific operation without
first loading the head operation (like we currently do). One reason
for that is of course efficiency. A possibly more important reason is
that the head operation may be conflicted, depending on how we decide
to deal with operation-level conflicts. In order to do that, it makes
sense to move the creation of the `OpStore` outside of the
`View`. That also suggests that the `.jj/view/op_store/` directory
should move to `.jj/op_store/`, so this patch also does that. That's
consistent with how `.jj/store/` is outside of `.jj/working_copy/`.
2021-03-06 09:52:00 -08:00
Martin von Zweigbergk
031a39ecba cleanup: fix lots of issues found in the lib crate by clippy
I had forgotten to pass `--workspace` to clippy all this time :P
2021-02-26 23:15:43 -08:00
Martin von Zweigbergk
72aebc9da3 view: replace View trait by enum with Readonly and Mutable variants 2021-02-13 08:31:41 -08:00
Martin von Zweigbergk
30939ca686 view: return &HashSet instead of Iterator
We want to be able to be able to do fast `.contains()` checks on the
result, so `Iterator` was a bad type. We probably should hide the
exact type (currently `HashSet` for both readonly and mutable views),
but we can do that later. I actually thought I'd want to use
`.contains()` for indiciting public-phase commits in the log output,
but of course want to also indicate ancestors as public. This still
seem like a step (mostly) in the right direction.
2021-01-16 13:00:05 -08:00
Martin von Zweigbergk
4db3d8d3a6 view: add tracking of "public" heads (copying Mercurial's phase concept)
Mercurial's "phase" concept is important for evolution, and it's also
useful for filtering out uninteresting commits from log
output. Commits are typically marked "public" when they are pushed to
a remote. The CLI prevents public commits from being rewritten. Public
commits cannot be obsolete (even if they have a successor, they won't
be considered obsolete like non-public commits would).

This commits just makes space for tracking the public heads in the
View.
2021-01-16 11:48:35 -08:00
Martin von Zweigbergk
f43880381f view: make sure we don't leave a dangling git ref
All commits in the view are supposed to be reachable from its
heads. If a head is removed and there are git refs pointing to
ancestors of it (or to the removed head itself), we should make that
ancestor a head.
2021-01-16 11:05:32 -08:00
Martin von Zweigbergk
1f593a4193 view: create helper for enforcing view's invariants
The only invariant we currently enforce is that the set of heads does
not include any ancestors of other commits in the set. I'm about to
make sure that we don't end up with dangling git refs (pointing to
commits no reachable from the heads). It will be useful to have a
single place to enforce that since we'll need to do the same thing
after updating the view as after merging views.
2021-01-16 10:35:46 -08:00
Martin von Zweigbergk
1f27a78957 view: make remove_head() not add parents as heads
I think it's better to let the caller decide if the parents should be
added. One use case for removing a head is when fetching from a Git
remote where a branch has been rewritten. In that case, it's probably
the best user experience to remove the old head. With the current
semantics of `View::remove_head()`, we would need to walk up the graph
to find a commit that's an ancestor and for each commit we remove as
head, its parents get temporarily added as heads. It's much easier for
callers that want to add the parents as heads to do that.
2021-01-15 01:08:05 -08:00
Martin von Zweigbergk
da0bbbe637 view: start tracking git refs
Git refs are important at least for understanding where the remote
branches are. This commit adds support for tracking them in the view
and makes `git::import_refs()` update them.

When merging views (either because of concurrent operations or when
undoing an earlier operation), there can be conflicts between git ref
changes. I ignored that for now and let the later operation win. That
will probably be good enough for a while. It's not hard to detect the
conflicts, but I haven't yet decided how to handle them. I'm leaning
towards representing the conflicting refs in the view just like how we
represent conflicting files in the tree.
2021-01-10 20:13:22 -08:00
Martin von Zweigbergk
3df6a92df6 view: merge concurrent operations ordered by transaction commit time
This will make it easier to test the result of concurrent operations
(just make sure the operations don't commit during the same
millisecond).
2021-01-10 19:34:52 -08:00
Martin von Zweigbergk
c4cd12e93e view: use the Operation wrapper type in merge_op_heads()
This is partly to prepare for merging the operations in order of
transaction-commit time (currently merged in order of operation id),
so we can get a predictable order in tests (assuming transactions are
not committed the same millisecond).
2021-01-10 19:34:52 -08:00
Martin von Zweigbergk
48e664c716 view: make the View types not store concrete OpStore type 2021-01-10 19:34:52 -08:00
Martin von Zweigbergk
905a5c97d6 transaction: make sure set of heads has only heads
`Transaction::add_head()` and others would let the caller add
non-heads to the set (i.e. ancestors of others heads) and the the
non-heads were filterd out when the transaction was committed. That's
a little surprising, so let's try to keep the set valid even within a
transaction. That will surely make commands that add many commits
noticeably slower in large repos. Hopefully we can improve that
later.
2020-12-29 20:44:17 -08:00
Martin von Zweigbergk
6b1427cb46 import commit 0f15be02bf4012c116636913562691a0aaa7aed2 from my hg repo 2020-12-12 00:23:38 -08:00