273 Commits

Author SHA1 Message Date
Martin von Zweigbergk
11525bfba0 repo: move resolving of concurrent operations to repo level (#111)
It's useful for the UI layer to know that there's been concurrent
operations, so it can inform the user that that happened. It'll be
even more useful when we soon start making the resolution involve
rebasing commits, since that's even more important for the UI layer to
present to the user. This patch gets us a bit closer to that by moving
the resolution to the repo level.
2022-03-26 22:31:49 -07:00
Martin von Zweigbergk
39838a76bf view: move merging of views up to repo level (#111)
I want to make it so when we apply a repo-level change that removes a
head, we rebase descendants of that head onto the closes visible
ancestor, or onto its successor if the head has been rewritten (see
#111 for details). The view itself doesn't have enough information for
that; we need repo-level information (to figure out relationships
between commits).

The view doesn't have enough information to do the.
2022-03-26 22:31:49 -07:00
Martin von Zweigbergk
a663a5d89c repo: don't abandon empty commit if it has descendants
It's unusual for the current commit to have descendants, but it can
happen. In particular, it can easily happen when you run `jj new`. You
probably don't want to abandon it in those cases.
2022-03-26 21:11:42 -07:00
Martin von Zweigbergk
7c247116b9 repo: remove code for upgrading old repos to have .jj/store/git/
1b6efdc3f8ed moved `.jj/git/` into `.jj/store/` for consistency with
the layout of native stores. It provided automatic format upgrades for
repos with the old format. It's been about four months now, so let's
remove the migration code.
2022-02-17 22:44:05 -08:00
Martin von Zweigbergk
a6ef792ba6 repo: initialize without checkouts, let Workspace add it (#13)
As part of creating a new repository, we create an open commit on top
of the root and set that as the current checkout. Now that we have
support for multiple checkouts in the model, we also have support for
zero checkouts, which means we don't need to create that commit on top
of the root when creating the repo. We can therefore move out of
`ReadonlyRepo`'s initialization code and let `Workspace` instead take
care of it. A user-visible effect of this change is that we now create
one operation for initilizing the repo and another one for checking
out the root commit. That seems fine, and will be consistent with the
additional operation we will create when adding further workspaces.
2022-02-02 11:09:12 -08:00
Martin von Zweigbergk
a41fcb39eb repo: respect workspace ID for old checkout (#13)
When checking out a new commit, we look at the old checkout to see if
it's empty so we should abandon it. We current use the default
workspace's checkout. We need to respect the workspace ID we're given
in `MutableRepo::check_out()`, and we need to be able to deal with
that workspace not existing yet (i.e. this being the first checkout in
that workspace).
2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
ac0d040bb5 rewrite: update all checkouts, not just the default workspace's (#13) 2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
6d3e2017f8 view: merge checkouts for all workspaces, not just the default one (#13) 2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
766c01a6d9 view: add workspace_id argument to set_checkout() (#13) 2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
0098edd3d2 op_store: add support for tracking multiple workspaces (#13)
This patch teaches the `View` object to keep track of the checkout in
each workspace. It serializes that information into the `OpStore`. For
compatibility with existing repos, the existing field for a single
workspace's checkout is interpreted as being for the workspace called
"default".

This is just an early step towards support for multiple
workspaces. Remaining things to do:

 * Record the workspace ID somewhere in `.jj/` (maybe in
   `.jj/working_copy/`)

 * Update existing code to use the workspace ID instead of assuming
   it's always "default" as we do after this patch

 * Add a way of indicating in `.jj/` that the repo lives elsewhere and
   make it possible to load a repo from such workspaces

 * Add a command for creating additional workspaces

 * Show each workspace's checkout in log output
2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
0725d4326d repo: don't create unused .jj/view/ directory 2022-01-28 21:27:13 -08:00
Martin von Zweigbergk
81edd92523 workspace: take over creation of .jj/working_copy/ from repo.rs (#13)
It's clearly `Workspace`'s job to create `.jj/working_copy/`, I must
have just forgotten to move it there.
2022-01-28 20:35:13 -08:00
Martin von Zweigbergk
5b93ae6d4b rewrite: make it possible to rebase descendants multiple times
Despite what the documentation said, we don't clear the record of
rewritten and abandoned commits at the end. This change fixes that,
and adds a test showing that it's possible to call
`MutableRepo::rebase_descendants()` multiple times.
2022-01-27 22:11:07 -08:00
Martin von Zweigbergk
10ebf35c27 repo: add a convenience function for rebasing all descendants
All non-test users of `create_descendant_rebaser()` just want to
rebase all commits, so let's make that easy.
2022-01-27 08:28:44 -08:00
Martin von Zweigbergk
69ff505338 view: replace start_modification() by Clone impl
I'm pretty sure the `start_modification()` function is a leftover from
when there was `ReadonlyView` and `MutableView`.
2022-01-05 15:11:07 -08:00
Martin von Zweigbergk
c678a89794 cleanup: fix some issues reported by new clippy and/or rustc 2021-12-10 14:12:45 -08:00
Martin von Zweigbergk
c058ffeed7 rewrite: avoid accessing MutRepo::view() when rebasing descendants
Since 94e03f5ac859, we lazily filter out non-heads from `View`'s set
of head. Accessing the `MutRepo::view()` triggers that filtering. This
patch makes `DescendantRebaser` not unnecessarily do that. That speeds
up the rebasing of 162 descendants in the git.git repo from ~3.6 s to
~330 ms. Rebasing 1272 descendants takes ~885 ms.
2021-12-08 08:49:42 -08:00
Martin von Zweigbergk
7b724512dd repo: don't use stale view when checking for changes
I recently (0c441d9558a1) made it so we don't create an operation when
nothing changed. Soon thereafter (94e03f5ac859), I broke that when I
introduced a cache-invalidation bug when I made the filtering-out of
non-heads be lazy. This patch fixes that and also adds a test to
prevent regressions.
2021-12-05 22:01:48 -08:00
Martin von Zweigbergk
d451c1adf8 cli: add .jj/ to .git/info/exclude when collocated
When initializing a jj repo in the same directory as its backing git
repo, add `.jj/` to `.git/info/exclude` so it doesn't show up to `git`
commands.

This is part of #44.
2021-12-01 17:18:08 -08:00
Martin von Zweigbergk
94e03f5ac8 repo: enforce view invariants lazily
It's very slow to remove non-heads from the set of heads every time we
add an head. For example, in the git.git repo, a no-op `jj git import`
takes ~15 s. This patch changes makes us just mark the set of heads
dirty when a commit has been added and then we remove non-heads when
needed. That cuts down the `jj git import` time to ~200 ms.
2021-12-01 16:18:23 -08:00
Martin von Zweigbergk
626fbee0dd cli: show Git HEAD in log output
It's useful to know which commit is checked out in the underlying Git
repo (if there is one), so let's show that. This patch indicates that
commit with `HEAD@git` in the log output. It's probably not very
useful when the Git repo is "internal" (i.e. stored inside `.jj/`),
because then it's unlikely to change often. I therefore considered not
showing it when the Git repo is internal. However, it turned out that
`HEAD` points to a non-existent branch in the repo I use, so it won't
get imported anyway (by the function added in the previous patch). We
can always review this decision later.

This is part of #44.
2021-12-01 11:08:53 -08:00
Martin von Zweigbergk
8a2f630ac0 git: start tracking HEAD of underlying Git repo
This patch adds a place for tracking the current `HEAD` commit in the
underlying Git repo. It updates `git::import_refs()` to record it. We
don't use it anywhere yet.

This is part of #44.
2021-12-01 11:08:53 -08:00
Martin von Zweigbergk
0c441d9558 cli: don't commit no-op transaction
If nothing changed in a transaction, it's rarely useful to commit it,
so let's avoid that. For example, if you run `jj git import` without
changing the anything in the Git repo, we now just print "Nothing
changed.".
2021-12-01 09:51:20 -08:00
Martin von Zweigbergk
f27f110d10 repo: remove now-unused working copy path 2021-11-25 21:14:24 -08:00
Martin von Zweigbergk
b4f2b88522 workspace: move initialization of WorkingCopy from ReadonlyRepo 2021-11-25 21:14:24 -08:00
Martin von Zweigbergk
c6cba59c27 workspace: move creation of .jj/ directory from Repo to Workspace 2021-11-25 21:08:43 -08:00
Martin von Zweigbergk
f17aced374 workspace: move search for .jj/ directory from Repo to Workspace 2021-11-25 21:08:43 -08:00
Martin von Zweigbergk
c08adba424 repo: remove working_copy(), only used in tests
This is another step towards removing coupling between the repo and
the working copy, so we can have multiple working copies for a single
repo (#13).
2021-11-25 21:04:56 -08:00
Martin von Zweigbergk
70073b94a8 repo: stop keeping a WorkingCopy instance
The `Repo` doesn't do anything with the `WorkingCopy` except keeping a
reference to it for its users to use. In fact, the entire lib crate
doesn't do antyhing with the `WorkingCopy`. It therefore seems simpler
to have the users of the crate manage the `WorkingCopy` instance. This
patch does that by letting `Workspace` own it. By not keeping an
instance in `Repo`, which is `Sync`, we can also drop the
`Arc<Mutex<>>` wrapping.

I left `Repo::working_copy()` for convenience for now, but now it
creates a new instance every time. It's only used in tests.

This further decoupling should help us add support for multiple
working copies (#13).
2021-11-25 21:04:56 -08:00
Martin von Zweigbergk
c0711f47cf workspace: introduce Workspace type
Having a concept of a "workspace" will be useful for adding support
for multiple workspaces (#13). You can think of the "workspace" as a
repo combined with a working copy. A workspace corresponds 1:1 with a
`.jj/` directory. It's pretty close to what other VCS simply call a
"repo", but I've ended up using the word "repo" for what Git calls a
"bare repo".
2021-11-25 21:04:56 -08:00
Martin von Zweigbergk
b35086d4c9 repo: use local variable for WorkingCopy in Repo::init()
No need to pass it into `Repo` and then get it back from there.
2021-11-17 10:22:15 -08:00
Martin von Zweigbergk
e901a4e66b repo: don't materialize conflicts on checkout
Since the working copy can now handle conflicts, we don't need to
materialize conflicts when checking out a commit.

Before this patch, we used to create a new commit on top whenever we
checked out a commit with conflicts. That new commit was intended just
for resolving the conflicts. The typical workflow was the resolve the
conflicts and then amend. To use the same workflow after this patch,
one needs to explicitly create a new commit on top with `jj new` after
checking out a commit with conflict.
2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
33bf6ce1d5 view: don't force commits pointed to by refs to be current heads
If you rewrite a commit that's also available on some remote, you'll
currently see both the old version and the new version in the view,
which means they're divergent. They're not logically divergent (the
rewritten version should replace the old version), so this is a UX
bug. I think it indicates that the set of current heads should be
redefined to be the *desired* heads. That's also what I had suspected
in the TODO removed by this change.  I think another indication that
we should hide the old heads even if they have e.g. a remote branch
pointing to them is that we don't want them to be rebased if we
rewrite an ancestor.

So that's what I decided to do: let the view's heads be the desired
heads. The user can still define revsets for showing non-current
commits pointed to by e.g. remote branches.
2021-10-23 09:15:05 -07:00
Martin von Zweigbergk
6722a79e27 repo: fix crash on upgrade of repo backed by external Git repo
If the repo is backed by Git repo that's not inside `.jj/`, then
there's no `.jj/git/` directory to move into `.jj/store/`.
2021-10-14 16:41:57 -07:00
Martin von Zweigbergk
97b48635f6 repo: move Backend initialization to Store
This is just a cleanup. Now only `Store` knows how to tell which
backend to use.
2021-10-13 23:55:16 -07:00
Martin von Zweigbergk
1b6efdc3f8 repo: make .jj/store a directory also in Git-backed repos
I think this is just cleaner, and it gives us room to put other
store-related data in the `.jj/store/` directory. I may want to use
that place for writing the metadata we currently write in Git notes
(#7).
2021-10-13 23:42:25 -07:00
Martin von Zweigbergk
dba72af857 repo: move creation of directories .jj/* directories closer and earlier 2021-10-13 22:49:37 -07:00
Martin von Zweigbergk
fdb861b957 backend: remove unused Commit::is_pruned (#32) 2021-10-06 23:53:15 -07:00
Martin von Zweigbergk
4c4e436f38 evolution: delete it now that we don't use it anymore (#32)
It's been a lot of work, but now we're finally able to remove the
`Evolution` state! `jj obslog` still works as before (it just walks
the predecessor pointers).
2021-10-06 23:28:30 -07:00
Martin von Zweigbergk
4c8beee81c Transaction: don't remove hidden heads on commit
The removal of hidden heads was just there to help with the transition
away from evolution (#32). Now that we no longer depend on evolution
for removing old heads, we can remove the hack.
2021-10-06 23:20:23 -07:00
Martin von Zweigbergk
108c38d816 evolution: don't create pruned commits (#32)
Now that we rebase descendants and remove old heads as appropriate
(without using evolution), we don't need to create pruned commits
anymore.
2021-10-06 23:20:23 -07:00
Martin von Zweigbergk
e26d21dc18 revset: add .commit_ids() and .commits() to RevsetIterator
This makes it a little easier to iterate over commits or commit ids.
2021-10-06 14:18:11 -07:00
Martin von Zweigbergk
a78976cd29 DescendantRebaser: allow passing divergent changes as input
I'm going to teach `DescendantRebaser` to also update local branches
pointing to rewritten commits, taking over the responsibility from
`rewrite::update_branches_after_rewrite()`. For commits that have been
rewritten as multiple new commits (divergent, not split), that
function makes local branches pointing to the old commit point to all
the new commits. To replicate that behavior in `DescendantRebaser`, it
needs to know about divergent changes. This change addresses that.
2021-10-02 23:12:46 -07:00
Martin von Zweigbergk
1c55c02106 Transaction: remove hidden heads on commit
I recently made the CLI remove hidden heads when a transaction is
committed (38474a9). Let's move that to `Transaction::commit()`, so
the library crate becomes more similar to how the CLI behaves and more
similar to our evolution-less future (#32).
2021-10-02 23:12:46 -07:00
Martin von Zweigbergk
5e0e90d81e MutableRepo: record old checkout abandoned if it's empty
Same reasoning as the previous change.

With this change, I believe we now record all rewritten and abandoned
commits correctly. We're now almost ready to switch the CLI away from
using evolution for automatically rebasing commits.
2021-09-29 20:47:23 -07:00
Martin von Zweigbergk
d00b805d97 MutableRepo: add support for recording rewritten and abandoned commits
When we remove support for evolution (#32), we need to still make it
easy for application code to rebase descendants of rewritten and
abandoned commits. The way applications currently do that is by using
e.g.  `CommitBuilder::for_rewrite_from()` followed by
`evolve_orphans()`. This patch puts some bookkeeping in `MutableRepo`
for rewritten and abandoned commits, along with a function for
creating a `DescendantRebaser` based on it. I'll then make
`CommitBuilder` record rewritten commits there.
2021-09-29 15:24:04 -07:00
Martin von Zweigbergk
736a0e7442 Transaction: don't wrap MutableRepo in Arc
I think this was a vestige from the time when `MutableEvolution` had a
back-reference into `MutableRepo` (at least I think it used to be that
way).
2021-09-29 10:13:32 -07:00
Martin von Zweigbergk
ff71af1e11 MutableRepo: accept just CommitId instead of whole Commit where possible 2021-09-29 10:13:32 -07:00
Martin von Zweigbergk
ae7f00e7b1 cli: rename jj prune to jj abandon
The command's help text says "Abandon a revision", which I think is a
good indication that the command's name should be `abandon`. This
patch renames the command and other user-facing occurrences of the
word. The remaining occurrences should be removed when I remove
support for evolution.
2021-09-19 22:51:12 -07:00
Martin von Zweigbergk
0c1ce664ea store: remove (weak) self-reference and take &Arc<Self> arguments instead
The `weak_self` stuff was from before I knew that `self` could be of
type `&Arc<Self>`.
2021-09-16 23:30:30 -07:00