ok/jj
1
0
Fork 0
forked from mirrors/jj
Commit graph

438 commits

Author SHA1 Message Date
Martin von Zweigbergk
c0ae4b16e8 trees: try to resolve file conflicts after simplifying conflicts
This fixes a bug I've run into somewhat frequently. What happens is
that if you have a conflict on top of another conflict and you resolve
the conflict in the bottom commit, we just simplify the `Conflict`
object in the second commit, but we don't try to resolve the new
conflict. That shows up as an unexpected "conflict" in `jj log`
output, and when you check out the commit, there are actually no
conflicts, so you can just `jj squash` right away.

This patch fixes that bug. It also teaches the code to work with more
than 3 parts in the merge, so if there's a 5-way conflict, for
example, we still try to resolve it if possible.
2021-10-22 09:20:50 -07:00
Martin von Zweigbergk
f1e2124a64 trees: make simplify_conflict() always return a Conflict
The interface is much cleaner this way. The function no longer makes
any writes to the store.
2021-10-20 22:07:42 -07:00
Martin von Zweigbergk
2e4dc019d9 git: don't update public heads for now 2021-10-20 14:23:58 -07:00
Martin von Zweigbergk
23c3e02134 stacked_table: don't expect a certain listing order from the file system 2021-10-20 13:53:32 -07:00
Martin von Zweigbergk
c260fea811 GitBackend: move extra metadata from Git notes to stacked-table storage
Git notes (at least as implemented by libgit2) quickly gets really
slow, as noted in issue #7. This patch replaces it by a custom storage
format.

I tested the performance in the git.git repo with just a few hundred
annotated commits (~450, I think) and no sharding. I listed the first
~2900 commits there using `jj log --no-graph -r ,,v1.0.0 -T 'author
"\n"' | wc -l`. That took about 882ms. After this patch, it dropped to
108ms.

I did a similar test in this repo with 12700 annotated commits and
sharding, listing all visible commits. That took 142ms before this
patch (the sharding helps a lot!) and 55ms after.

Closes #3.
Closes #7.
2021-10-20 13:22:59 -07:00
Martin von Zweigbergk
deddd90762 stacked_table: add caching of tables
We don't want to re-read the whole table(s) every time we read extra
metadata for a commit (which is the immediate use-case I'm aiming for
in #7)..
2021-10-20 13:22:36 -07:00
Martin von Zweigbergk
85773cf81f stacked_table: add a generic store based on the stacked-table format
The new store works the same way as the `OpHeadsStore`. It keeps track
of the current head file(s) by recording their names in a
directory. When a write happens, it adds the new head and then removes
the old head. There will be generally be a single head at a time. The
only exception is when there's been concurrent operations (locally, or
remotely, in the case of a distributed file system). When there are
multiple heads files, they are automatically merged. No guarantee is
given about which value wins if the key exists in several heads; the
store is meant to be used for data that's immutable once written. As
long as different keys are written, this is a CRDT. That makes it fit
for solving both #3 and #7.
2021-10-20 13:21:12 -07:00
Martin von Zweigbergk
e86d266e6b stacked_table: add a file format for stacked, sorted tables
I'm trying to replace the Git backend's use of Git notes for storing
metadata (#7). This patch adds a file format that I hope can be used
for that. It's a simple generic format for storing fixed-size keys and
associated variable-size values. The keys are stored in sorted
order. Each key is followed by an offset to the value. The offset is
relative to the first value. All values are concatenated after each
other. I suppose it's a bit like Git's pack files but lacking both
delta-encoding and compression.

Each file can also have a parent pointer (just like the index files
have), so we don't have to rewrite the whole file each time. As with
the index files, the new format squashes a file into its parent if it
contains more than half the number of entries of the parent. The code
is also based on `index.rs`.

Perhaps we can alo replace the default operation storage with this
format. Maybe also the native local backend's storage. We'll need
delta-encoding and compression soon then.
2021-10-20 13:19:32 -07:00
Martin von Zweigbergk
d8795b9ae7 store: move logic for initialization of GitBackend to that type 2021-10-18 08:49:22 -07:00
Martin von Zweigbergk
e8f44fb470 index: remove predecessor information from the index
Since we removed the evolution state in commit 4c4e436f38, we no
longer use the predecessor information in the index, so let's remove
it.
2021-10-17 09:13:31 -07:00
Martin von Zweigbergk
0354b8721b index: transparently reindex if the index is corrupt
I'm about to change the index format (to remove predecessor
information), which will break the format. Let's prepare for that by
having `IndexStore` reindex the repo if it fails to read the index..
2021-10-17 09:13:31 -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
c0a26f7642 conflicts: work around rust-lang/rust#89716 2021-10-13 13:41:09 -07:00
Martin von Zweigbergk
b4b64eb7e5 conflicts: add tests of conflict materialization 2021-10-13 13:40:25 -07:00
Martin von Zweigbergk
d8c0282873 revset: make head() accept candidate set to find heads within
With this change, you can do e.g. `heads(remote_branches())`. That
should currently be the same as `public_heads()`, except that we don't
yet remove public heads when remote branches have been updated. Having
this support should be generally useful, but I may use it in the short
term specifically for depending less on the public heads, until I get
around to keeping them up to date.
2021-10-13 09:41:20 -07:00
Martin von Zweigbergk
aebdd4e8fd revset: add all() function 2021-10-13 09:28:11 -07:00
Martin von Zweigbergk
5874d5abfb revset: add none() function 2021-10-13 09:24:08 -07:00
Martin von Zweigbergk
8bbfe9731e cleanup: let newer Clippy fix a few things it found 2021-10-13 08:27:44 -07:00
Martin von Zweigbergk
94408f01e0 revset: extract a function for creating a revset from commit ids
This is just to avoid some repetition.
2021-10-10 12:44:35 -07:00
Martin von Zweigbergk
8465a578be revset: split out a new remote_branches() from branches()
It seems useful to be able to use `remote_branches()` in revsets
e.g. for filtering out commits known on remotes.
2021-10-10 12:24:48 -07:00
Martin von Zweigbergk
e52c902d3a diff: compact adjacent unchanged regions also when using for_tokenizer()
I noticed while working on support for unified diffs (#33) that
`Diff::for_tokenizer(..., &find_line_ranges)` would return a
`DiffHunk::Matching` for each matching line instead of a single
`DiffHunk::Matching` for all the matching lines. That's different from
what you get from `Diff::default_refinement()` and seems less
convenient to work with.
2021-10-10 00:00:06 -07:00
Martin von Zweigbergk
28a2c534a0 git: add support for password-less SSH keys
My SSH keys are password-protected, so I haven't been able to test
this patch completely, but I believe it should work. We now use
ssh-agent if `$SSH_AGENT_PID` is set, otherwise we check if
`$HOME/.ssh/id_rsa` exists and assume it's a password-less key. That's
quite hacky but I think it's good enough for now. We eventually need
to move this out of the library crate just like libgit2 has done.

Closes #25.
2021-10-09 09:44:57 -07:00
Martin von Zweigbergk
fc883d1d02 git: extract a function for creating RemoteCallbacks 2021-10-09 09:12:03 -07:00
Martin von Zweigbergk
d434b948f1 git: use git's HTTP proxy configs
I don't have an HTTP proxy to test with, but I hope this is all that's
needed.

Closes #34.
2021-10-09 09:01:47 -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
56c7f32023 revset: avoid using evolution for resolving a change id to its commits
This rewrites the code for resolving a change id to simply walk the
entire index. That's obviously not optimal, but it's not worse than
what we did in the evolution-based resolution. This is yet another
step towards removing support for evolution (#32).
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
b7acbae168 DescendantRebaser: also remove old heads
This patch teaches `DescendantRebaser` to also update heads. That's
done at the end of the rebase (when `rebase_next()` starts returning
`None`), which is a little weird. We should probably change the
interface, but this will do for now.

With this change, we should no longer need to remove hidden heads when
the transaction commits. That will remove one of the last bits of
dependence on evolution from most commands (#32).
2021-10-06 22:01:39 -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
41779551fb revsets: remove heads arguments from builder API functions
Now that we no longer have to be careful whether we mean "all heads"
or "non-obsolete heads", there's no need to pass them as
arguments. It's still possible to get a DAG range to a hidden commit
by using `RevsetExpression::dag_range_to()`, as long as the hidden
commit is indexed.
2021-10-06 13:28:51 -07:00
Martin von Zweigbergk
9ec27645cf revsets: remove all_heads()
Now that we remove hidden heads whenever a transaction commits,
`non_obsolete_heads()` should always be the same as `all_heads()`,
except during a transaction. I don't think we depend on the difference
even during a transaction. Let's simplify a bit by removing the revset
function `all_heads()` and renaming `non_obsolete_heads()` to
`heads()`. This is part of issue #32.
2021-10-06 12:21:18 -07:00
Martin von Zweigbergk
f3bee0b12e evolution: remove support evolving orphans and divergent commits (#32) 2021-10-03 22:38:49 -07:00
Martin von Zweigbergk
fcb79ef0a6 DescendantRebaser: also update checkout (#32)
This is similar to how a recent change taught `DescendantRebaser` to
update branches pointing to rewritten commits. Now we also update the
checkout if it pointed to a rewritten commit.
2021-10-03 22:38:49 -07:00
Martin von Zweigbergk
5be75d0e31 DescendantRebaser: also update branches
This patch moves the logic for updating branches from
`update_branches_after_rewrite()` into `DescendantRebaser`. The
branches are now updated along with each rebased commit rather than
all being updated at the end. The new code uses the information about
rewritten and abandoned commits that `DescendantRebaser` gets from
`MutableRepo`. That is different from the old code, which used the
evolution state. This patch thus moves us one step closer to removing
evolution (#32).
2021-10-03 10:07:09 -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
de0df90b66 tests: use letters instead of numbers for commits in test_rewrite
Letters let you make it clearer by using e.g. "X2" for a rewritten
commit "X"..
2021-10-02 23:12:46 -07:00
Martin von Zweigbergk
04c313462b DescendantRebaser: minor cleanups and refactoring 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
41ebdea415 tests: update a test to not point a branch to an unreachable commit
The next patch would otherwise make this test fail because
"transaction 2" tries to point a branch to a commit that's not visible
(because it's created by the concurrent "transaction 1").
2021-10-02 23:08:45 -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
76352564ad CommitBuilder: record rewritten commits in MutableRepo
This is part of removing support for evolution (#32). Since
`CommitBuilder` now records rewritten commits in `MutableRepo`, we can
use that recorded information to automatically rebase descendants.
2021-09-29 15:45:38 -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
23c3b503c0 tests: move assert_rebased() function to testutils 2021-09-29 11:41:51 -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