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

83 commits

Author SHA1 Message Date
Martin von Zweigbergk
e7a7cb8ea5 gitignores: remove error type that's never instantiated 2022-03-12 10:48:06 -08:00
Martin von Zweigbergk
03e6b8c0e6 working_copy: take Tree, not CommitId, as argument to check_out()
We no longer need the commit ID, so we shouldn't make the callers pass
it. This lets us simplify several tests, because they no longer to
create commits just to check out a tree in the working copy.
2022-02-13 12:14:34 -08:00
Martin von Zweigbergk
315e5e87a3 working_copy: take a tree object instead of ID in TreeState::check_out()
The callers mostly have the tree object available anyway.
2022-02-13 12:12:08 -08:00
Martin von Zweigbergk
00c9a1ae11 working_copy: stop taking commit ID in LockedWorkingCopy::finish()
We used to use the value to detect races, but we use the tree ID and
the operation ID these days, so we don't need the commit ID.

By changing this, we can avoid creating some commit IDs in tests,
which is why I tackled this issue now.
2022-02-12 23:48:06 -08:00
Martin von Zweigbergk
cde3609163 working_copy: stop taking initial checkout in constructor
We don't use the value anymore.
2022-02-12 23:45:05 -08:00
Martin von Zweigbergk
993de96fc7 working_copy: stop keeping track of commit ID 2022-02-12 17:22:37 -08:00
Martin von Zweigbergk
e098c01935 working_copy: replace commit ID by tree ID for checking for changes
What matters for the working copy is the tree ID. We should be able to
remove the commit ID. This patch gets us close.
2022-02-12 17:16:19 -08:00
Martin von Zweigbergk
537b1de7d9 working_copy: move check of old commit ID on checkout to higher level
There are only two callers of `LockedWorkingCopy::check_out()`. One is
in `commands.rs`. That caller already checks after taking the lock
that the old commit ID is as expected. The other caller is
`WorkingCopy::check_out()`. We can simply move the check to that level
since it's the only caller that cares now.
2022-02-12 14:27:40 -08:00
Martin von Zweigbergk
b74851e005 working_copy: make sure discarded update is not visible
`LockedWorkingCopy::discard()` shouldn't result in changes to the
on-disk state, but `LockedWorkingCopy::check_out()` may have already
written a state file, which is surprising. The changes also remain in
memory, which is also surprising. Let's fix both of those issues.
2022-02-09 10:40:51 -08:00
Martin von Zweigbergk
c09a4e15c5 workspace: add a function for initializing additional workspace (#13) 2022-02-02 17:00:03 -08:00
Martin von Zweigbergk
fb8fbdc4b3 working_copy: keep track of workspace ID (#13)
This patch makes it so the workspace ID can be stored in
`.jj/working_copy/checkout`. The workspace ID is still always
"default".
2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
38180555de working_copy: keep track of operation ID (#13)
When there are concurrent operations that want to update the working
copy, it's useful to know which operation was the last to successfully
update the working copy. That can help use decide how to resolve a
mismatch between the repo view's record and the working copy's
record. If we detect such a difference, we can look at the working
copy's operation ID to see if it was updated by an operation before or
after we loaded the repo.

If the working copy's record says that it was updated at operation A
and we have loaded the repo at operation B (after A), we know that the
working copy is stale, so we can automatically update it (or tell the
user to run some command to update it if we think that's more
user-friendly).

Conversely, if we have loaded the repo at operation A and the working
copy's record says that it was updated at operation B, we know that
there was some concurrent operation that updated it. We can then
decide to print a warning telling the user that we skipped updating
because of the conflict. We already have logic for not updating the
working copy if the repo is loaded at an earlier operation, but maybe
we can drop that if we record the operation in the working copy (as
this patch does).
2022-01-19 19:15:29 -08:00
Martin von Zweigbergk
419efb88f9 working_copy: update stale comment on LockedWorkingCopy
The recent refactoring introducing `WorkgingCopy::start_mutation()`
(25d19e8a65) made this comment incorrect.
2022-01-19 15:12:45 -08:00
Martin von Zweigbergk
45a00e819d working_copy: pass only a TreeId to LockedWorkingCopy::check_out()
It only needs a `TreeId`.
2022-01-19 09:04:01 -08:00
Martin von Zweigbergk
fabaf8b608 working_copy: move logic of check_out() onto LockedWorkingCopy
Having the checkout functionality in `LockedWorkingCopy` makes it a
little more flexible (one could imagine using it for udating working
copy files and then discarding the state changes, for example). It
also lets us reuse a few lines of code for locking. I left
`WorkingCopy::check_out()` for convenience because that's what all
current users want.
2022-01-19 09:04:01 -08:00
Martin von Zweigbergk
9e1869dcef working_copy: pass in old commit ID to check_out()
`WorkingCopy::check_out()` currently fails if the commit recorded on
disk has changed since it was last read. It fails with a "concurrent
checkout" error. That usually works well in practice, but one can
imagine cases where it's not correct. For an example where the current
behavior is wrong, consider this sequence of events:

 1. Process A loads the repo and working copy.

 2. Process B loads the repo at operation A. It has not loaded the
    working copy yet.

 3. Process A writes an operation and updates the working copy.

 4. Process B loads the working copy and sees that it is checked out
    to the commit process B set it to. We don't currently have any
    checks that the working copy commit matches the view's checkout
    (though I plan to add that).

 5. Process B finishes its operation (which is now divergent with the
    operation written by process A). It updates the working copy to
    the checkout set in the repo view by process B. There's no data
    loss here, but the behavior is surprising because we would usually
    tell the user that we detected a concurrent update to the working
    copy.

We should instead check that the working copy's commit on disk matches
what the previous repo view said, i.e. the view at the start of the
operation we just committed. This patch does that by having the caller
pass in the expected old commit ID.
2022-01-19 09:04:01 -08:00
Martin von Zweigbergk
8c97fdf5d6 working_copy: remove untrack() now that we have more flexible reset() 2022-01-19 09:04:01 -08:00
Martin von Zweigbergk
cd4fbd3565 working_copy: add a reset() function for Git-like reset
We already have two usecases that can be modeled as updating the
`TreeState` without touching the working copy:

 1. `jj untrack` can be implemented as removing paths from the tree
    object and then doing a reset of the working copy state.

 2. Importing Git HEAD when sharing the working copy with a Git repo.

This patch adds that functionality to `TreeState`.
2022-01-19 08:32:59 -08:00
Martin von Zweigbergk
9a640bfe13 working_copy: save TreeState later, just before releasing lock
I was surprised that we save the `TreeState` before
`LockedWorkingCopy::finish()`. That means that even if the caller
instead decides to discard the changes, some changes will already have
been written.
2022-01-19 08:32:59 -08:00
Martin von Zweigbergk
25d19e8a65 working_copy: start improving interface for mutations
This patch changes the interface for making changes to the working
copy by replacing `write_tree()` and `untrack()` by a single
`start_mutation()` method. The two functions now live on the returned
`LockedWorkingCopy` object instead. That is more flexible because the
caller can make multiple changes while the working copy is locked. It
also helps us reduce the risk of buggy callers that read the commit ID
before taking the lock, because we can now make it accessible only on
`LockedWorkingCopy`.
2022-01-19 08:32:59 -08:00
Martin von Zweigbergk
2916dc3423 working_copy: make a &mut self argument not mutable 2022-01-19 08:32:51 -08:00
Martin von Zweigbergk
1fc19dbbaf working_copy: take initial commit in init() function
The working copy object knows the currently checked out commit ID. It
is set to `None` when the object is initialized. It is also set to
`None` when an existing working copy is loaded. In that case, it's
used only to facilitate lazy loading. However, that means that
`WorkingCopy::current_commit_id()` fails if the working copy has been
initalized but no checkout has been specified. I've never run into
that case, but it's ugly that it can happen. This patch fixes it by
having `WorkingCopy::init()` take a `CommitId`.
2022-01-17 14:12:55 -08:00
Martin von Zweigbergk
0fadac38d6 working_copy: remove current_commit() (leaving current_commit_id()
`WorkingCopy::current_commit()` has been there from the beginning. It
has made less sense since we made the repo view keep track of the
current checkout. Let's remove it.
2022-01-15 17:11:56 -08:00
Martin von Zweigbergk
1f68de64d4 debug: upgrade Drop implementations to non-debug assert!
I think these remaining implementations of `Drop` are for types that
are infrequently dropped (unlike `Transaction`), so it be fine to be
more strict about them.
2021-12-01 10:32:11 -08:00
Martin von Zweigbergk
8cf5dd286a backend: make Vec inside CommitId non-public
The recent e5dd93cbf7, whose description says "cleanup: make Vec
inside CommitId etc. non-public", made all ID types in the `backend`
module *except* for `CommitId` non-public :P This patch makes
2021-11-19 23:19:00 -08:00
Martin von Zweigbergk
33b272f5fa working_copy: make some functions require mutable references
We use interior mutability for caching in `WorkingCopy`, but let's
still take mutable reference in the functions where the state change
is visible.
2021-11-17 10:15:33 -08:00
Martin von Zweigbergk
287602966e working_copy: add a method for untracking specified paths 2021-11-17 08:41:37 -08:00
Martin von Zweigbergk
e5dd93cbf7 cleanup: make Vec inside CommitId etc. non-public 2021-11-10 10:46:10 -08:00
Martin von Zweigbergk
ea82340654 working_copy: preserve conflicts in the working copy until markers are removed
I realized only recently that we can try to parse conflict markers in
files and leave them as conflicted if they haven't changed. If they
have changed and some conflict markers have been removed, we can even
update the conflict with that partial resolution.

This change teaches the working copy to write conflicts to the working
copy. It used to expect that the caller had already updated the tree
by materializing conflicts. With this change, we also start parsing
the conflict markers and leave the conflicts unresolved in the working
copy if the conflict markers remain.

There are some cases that we don't handle yet. For example, we don't
even try to set the executable bit correctly when we write
conflicts. OTOH, we didn't do that even before this change.

We still never actually write conflicts to the working copy (outside
of tests) because we currently materialize conflicts in
`MutRepo::check_out()`. I'll change that next.
2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
856b219943 working_copy: if a file's recorded mtime is equal to the state's mtime, set to 0 early 2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
033bfe7d5b working_copy: fix an incorrect comment about timestamps 2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
9ac643ed1a working_copy: rename confusingly named read_time field 2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
baa403b41e working_copy: clarify code for preserving current file state
On Windows, we preserve the executable bit. I plan to also teach the
working copy to preserve conflict state. This refactoring prepares for
that by simplifying how we preserve parts of the current file state.
2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
7c12014513 working_copy: extract a function for updating the file state and tree if dirty 2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
730c442462 working_copy: move file_state() off of TreeState
The function doesn't use `self`, so let's move it off of
`TreeState`. That way we can call it even while holding a mutable
reference.
2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
f86ffbd47b working_copy: take advantage of DirEntry::path() 2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
5dce6e9884 working_copy: avoid using file_state() for getting mtime of tree_state file
I want to change the signature of `file_state()` and this caller is
different from the others and only needs the mtime.
2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
efe7316354 working_copy: make FileType variants more similar to TreeValue variants
This change doesn't make much difference yet, but I think it will
enable further improvements.
2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
bf61e9cf3e working_copy: don't stat ignored files 2021-11-07 15:17:51 -08:00
Martin von Zweigbergk
ce5e95fa80 store: rename Store to Backend and StoreWrapper to Store
For what's currently called `Store` in the code, I have been using
"backend" in plain text. That probably means that `Backend` is a good
name for it.
2021-09-12 12:02:10 -07:00
Martin von Zweigbergk
49e1462fe5 working_copy: delete two obsolete TODOs about ignores
We have had support for ignores via `.gitignore` files since
3b326a942c, and we haven't had the problem with the temporary
`.git/` directory created by libgit2 since 88f7f4732b.
2021-09-03 23:10:45 -07:00
Martin von Zweigbergk
ccdd651953 working_copy: ignore .git directory/file when writing tree to store
Git doesn't want `.git` entries in its trees, so at least when using
the Git backend, we need to ignore such paths. Let's just ignore
`.git` paths regardless of backend to keep it simple.

Closes #24.
2021-09-01 08:40:28 -07:00
Martin von Zweigbergk
2afed65132 working_copy: move logic for creating commit to caller
The auto-rebasing of descendants doesn't work if you have an open
commit checked out, which means that you may still end up with orphans
in that case (though that's usually a short-lived problem since they
get rebased when you close the commit). I'm also about to make
branches update to successors, but that also doesn't work when the
branch is on a working copy commit that gets rewritten. To fix this
problem, I've decided to let the caller of `WorkingCopy::commit()`
responsible for the transaction.

I expect that some of the code that this change moves from the lib
crate to the cli crate will later move back into the lib crate in some
form.
2021-08-15 18:55:09 -07:00
Martin von Zweigbergk
7360589246 working_copy: consider it an error if temp file cannot be renamed to target
Unlike the other places I fixed in 134940d2bb, the calls in
`working_copy.rs` should not simply use an existing file if the target
file was open. They should probably try again instead, but I'll leave
that for later.
2021-06-16 10:52:55 -07:00
Martin von Zweigbergk
4c416dd864 cleanup: let Clippy fix a bunch of warnings 2021-06-14 00:27:31 -07:00
Martin von Zweigbergk
134940d2bb windows: don't fail when concurrent threads/processes fail to rename file
On Windows, it seems that you can't rename a file if the target file
is open (Stebalien/tempfile#131). I think that's the reason for our
failing tests on Windows. This patch adds a simple wrapper around
`NamedTempFile::persist()` that returns the existing file instead of
failing, if there is one.
2021-06-14 00:09:22 -07:00
Martin von Zweigbergk
f26c9f01ce working_copy: silence some warnings about unused code on Windows 2021-06-13 22:34:33 -07:00
Martin von Zweigbergk
dd4c47f373 tree: support filtering diff by matcher
This change teaches `Tree::diff()` to filter by a matcher. It only
filters the result so far; it does not restrict the tree walk to what
`Matcher::visit()` says is necessary yet. It also doesn't teach the
CLI to create a matcher and pass it in.
2021-06-09 16:26:58 -07:00
Martin von Zweigbergk
fdeb499836 trees: merge into tree module 2021-06-05 14:20:07 -07:00
Martin von Zweigbergk
54f6165ef1 repo_path: replace remaining uses of DirRepoPath by RepoPath 2021-05-19 15:11:04 -07:00