96 Commits

Author SHA1 Message Date
Yuya Nishihara
0a1bc2ba42 repo_path: add stub RepoPathBuf type, update callers
Most RepoPath::from_internal_string() callers will be migrated to the function
that returns &RepoPath, and cloning &RepoPath won't work.
2023-11-28 07:33:28 +09:00
Yuya Nishihara
d322df0c8d matchers: make Files/PrefixMatcher constructors accept slice of borrowed paths
RepoPath will become slice type (like str), and it doesn't make sense to
require &[RepoPathBuf] here.
2023-11-28 07:33:28 +09:00
Ilya Grigoriev
ea22f90018 cli editor and pager: Add a comment
Follows up on 13c93d52705.

The information I added is explained in that commit's description, but
I feel like it could reduce confusion for future readers of the code.
2023-11-22 23:36:16 -08:00
Yuya Nishihara
13c93d5270 cli: show executable name in error message, include underlying error details
Since this is the error to spawn (or wait) process, command arguments aren't
important. Let's make that clear by not showing full command string.

#2614
2023-11-23 10:05:45 +09:00
Yuya Nishihara
31def4b131 cleanup: don't use debug format to print source errors 2023-11-23 10:05:37 +09:00
Yuya Nishihara
6c98dfcdcb git: have import_refs() obtain git2::Repository instance from store
This helps gitoxide migration. It's theoretically possible to import Git refs
from non-Git backend, but I don't think such API flexibility is needed.
2023-11-14 17:35:27 +09:00
Yuya Nishihara
8e143541a5 operation: propagate OpStoreError from parents()
We need to .collect_vec() the parents iterator to temporary buffer since the
borrowed iterator can't be returned back to the dag_walk functions. Another
option is to clone op_store and parent ids to remove &self lifetime from the
iterator, but that also means a temporary Vec is created.
2023-11-14 07:16:39 +09:00
Yuya Nishihara
0251c9fe51 cli: propagate read_operation() errors
This is easy one. op.parents() can still panic, which would be a bit more
involved to fix.

#2549
2023-11-11 22:35:40 +09:00
Yuya Nishihara
4ab8a1ae6e cli: flatten check_stale_working_copy() result
I'll make it propagate OpStoreError, but OpStoreError is quite different
from the existing StaleWorkingCopyError. I think this error isn't actually
an "error" but a description of the working copy state.
2023-11-11 22:35:40 +09:00
Yuya Nishihara
6125fb160e op_store: embed details in operation/view not found error
This is basically a copy of BackendError::ObjectNotFound. The failed id may
be either view or operation id.
2023-11-11 22:35:40 +09:00
Austin Seipp
17bcac6838 cli: move resolve_destination_revs to cli_utils and rename
Summary: This is currently used by `new.rs`, `workspace.rs`, and `rebase.rs`,
and may be useful for other commands and custom CLIs. So just go ahead and move
it into the parent module hierarchy.

Also rename the function to `resolve_all_revs`, as it isn't actually specific to
rebase at all.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
Change-Id: I0ea12afd8107f95a37a91340820221a0
2023-11-04 10:26:08 -05:00
Martin von Zweigbergk
3a378dc234 cli: add a function for restoring part of a tree from another tree
We had similar code in two places for restoring paths from one tree to
another. Let's reuse it instead.

I put the new function in the `rewrite` module. I'm not sure if that's
right place. Maybe it belongs in `tree`?
2023-11-02 06:07:45 -07:00
Yuya Nishihara
162dcd49b4 cli: rewrite base GitIgnoreFile lookup to use gitoxide instead of libgit2
Since gix::Repository::config_snapshot() borrows the repo instance, it has to
be allocated in caller's stack. That's why GitBackend::git_config() is removed.
2023-11-02 19:33:06 +09:00
Ilya Grigoriev
b482898924 immutable commits: remove the hint if trying to edit the root commit
The hint is a bit misleading in this case. I also changed the message slightly.
2023-10-29 21:13:39 -07:00
Martin von Zweigbergk
a1ef9dc845 merged_tree: propagate backend errors in diff iterator
I want to fix error propagation before I start using async in this
code. This makes the diff iterator propagate errors from reading tree
objects.

Errors include the path and don't stop the iteration. The idea is that
we should be able to show the user an error inline in diff output if
we failed to read a tree. That's going to be especially useful for
backends that can return `BackendError::AccessDenied`. That error
variant doesn't yet exist, but I plan to add it, and use it in
Google's internal backend.
2023-10-26 06:20:56 -07:00
Yuya Nishihara
09529b63e5 cli: move parse_name_pattern() to cli_util, rename the function
We'll use it in git subcommands.
2023-10-25 03:58:48 +09:00
Yuya Nishihara
eb2f2783df cli: use StringPattern to find branches to delete/forget
The error message for unmatched patterns is adjusted so that it can be applied
to both exact and glob patterns.
2023-10-22 04:07:49 +09:00
Martin von Zweigbergk
c3b45b6fd1 workspace: make working-copy type customizable
This add support for custom `jj` binaries to use custom working-copy
backends. It works in the same way as with the other backends, i.e. we
write a `.jj/working_copy/type` file when the working copy is
initialized, and then we let that file control which implementation to
use (see previous commit).

I included an example of a (useless) working-copy implementation. I
hope we can figure out a way to test the examples some day.
2023-10-16 22:33:44 -07:00
Martin von Zweigbergk
6bfd618275 workspace: load working copy implementation dynamically
This makes `Workspace::load()` look a new `.jj/working_copy/type` file
in order to load the right working copy implementation, just like
`Repo::load()` picks the right backends based on `.jj/store/type`,
`.jj/op_store/type`, etc. We don't write the file yet, and we don't
have a way of adding alternative working copy implementations, so it
will always be `LocalWorkingCopy` for now.
2023-10-16 22:33:44 -07:00
Martin von Zweigbergk
e1f00d9426 working copy: pass commit instead of tree into check_out()
Our internal working copy implementations at Google will need the
commit so they can walk history backwards until they get to a "public"
commit. They'll then use that to tell build tools and virtual file
systems to present that as a base.

I'm not sure if we'll need to update `reset()` too. It's currently
only used by `jj untrack`, which doesn't change the commit's parent,
so it wouldn't affect any history walks.
2023-10-16 22:33:44 -07:00
Martin von Zweigbergk
0582893144 working copy: return Box<dyn LockedWorkingCopy> from start_mutation() 2023-10-15 16:13:19 -07:00
Martin von Zweigbergk
580586d008 working copy: return Box<dyn WorkingCopy> from finish() 2023-10-15 16:13:19 -07:00
Martin von Zweigbergk
63654d064b working copy: add sparse pattern functions to backend trait 2023-10-15 15:59:49 -07:00
Martin von Zweigbergk
6457a13260 working copy: add reset() function to the backend trait
This includes documenting the new function and the other types moved
to the `working_copy` module.
2023-10-15 15:59:49 -07:00
Martin von Zweigbergk
0d2247b0df working copy: add check_out() function to the backend trait
This includes documenting the new function and the other types moved
to the `working_copy` module.
2023-10-15 15:59:49 -07:00
Martin von Zweigbergk
781859cb51 working copy: add snapshot() function to the backend trait
This includes documenting the new function and the other types moved
to the `working_copy` module.
2023-10-15 15:59:49 -07:00
Martin von Zweigbergk
3aa57b1a04 working copy: start defining a trait for a locked working copy
As with the `WorkingCopy` trait, this just contains some trivial
methods for now.
2023-10-15 15:59:49 -07:00
Martin von Zweigbergk
c8184845d7 workspace: replace working_copy_mut() by wrapper type
I'm about to make `LockedLocalWorkingCopy` not borrow from
`LocalWorkingCopy`. That will make it easier to forget to update any
`LocalWorkingCopy` variables when the modifications have been
committed. This patch introduces a wrapper around
`LockedLocalWorkingCopy` to help prevent that.

Thanks to Yuya for the suggestion.
2023-10-15 15:59:49 -07:00
Martin von Zweigbergk
35f9c12cb5 working copy: move LocalWorkingCopy::check_out() to Workspace
`LocalWorkingCopy::check_out()` can be expressed using the planned
`WorkingCopy` trait, so it doesn't need to be in the trait itself
`WorkingCopy`. I wasn't sure if I should make it a free function in
`working_copy`, but I ended up moving it onto `Workspace`.
2023-10-15 15:59:49 -07:00
Martin von Zweigbergk
9e43207911 working copy: don't expose TreeStateError in LocalWorkingCopy API
The `TreeStateError` type is specific to the current local-disk
working-copy backend, so it should not be part of the generic
working-copy interface I'm trying to create.
2023-10-12 16:10:38 -07:00
Martin von Zweigbergk
33d27ed09f working copy: start defining a working copy trait
This just extracts a trait for the trivial bits to start with.
2023-10-12 16:10:38 -07:00
Martin von Zweigbergk
ebec82ee0c cli: allow overwriting non-scalar with jj config set
Before this patch, it was an error to run `jj config set --user foo
'[1]'` twice. But it's only been broken since the previous commit
because '[1]' was interpreted as a string before then.
2023-10-11 07:40:08 -07:00
Martin von Zweigbergk
f654801c20 cli: accept TOML arrays and tables to jj config set 2023-10-11 07:40:08 -07:00
Yuya Nishihara
7a3e72415c cli: send status messages to stderr, specify stdout/stderr explicitly
Many of &mut UI can be changed to immutable borrows, but I'm not gonna
update them in this patch.
2023-10-11 19:24:01 +09:00
Martin von Zweigbergk
44eb902171 working_copy: don't crash when updating and tracked file exits on disk
Before this patch, when updating to a commit that has a file that's
currently an ignored file on disk, jj would crash. After this patch,
we instead leave the conflicting files or directories on disk. We
print a helpful message about how to inspect the differences between
the intended working copy and the actual working copy, and how to
discard the unintended changes.

Closes #976.
2023-10-07 14:02:31 -07:00
Martin von Zweigbergk
187ba9430a working_copy: rename to local_working_copy
It's about time we make the working copy a pluggable backend like we
have for the other storage. We will use it at Google for at least two
reasons:

 * To support our virtual file system. That will be a completely
   separate working copy backend, which will interact with the virtual
   file system to update and snapshot the working copy.

 * On local disk, we need to tell our build system where to find the
   paths that are not in the sparse patterns. We plan to do that by
   wrapping the standard local working copy backend (the one moved in
   this commit), writing a symlink that points to the mainline commit
   where the "background" files can be read from.

Let's start by renaming the exising implementation to
`local_working_copy`.
2023-10-07 08:19:03 -07:00
Yuya Nishihara
be3d588449 cli: inline export_head_to_git(), use the same wc_commit to update working copy 2023-10-04 01:43:34 +09:00
Yuya Nishihara
df716888c9 cli: reorder working-copy commit lookup bits in finish_transaction()
Just to make the next commit look slightly nicer. tx.mut_repo() is no longer
assigned to local variable to narrow scope of mutable borrow.
2023-10-04 01:43:34 +09:00
Yuya Nishihara
7ccbc0424c git: extract function that resets Git HEAD
I'll add a workaround for the root parent issue #1495 there. We can pass in
the wc parent id instead of the wc_commit object, but we might want to use
wc_commit.id() to generate a unique placeholder ref name.
2023-10-04 01:43:34 +09:00
Yuya Nishihara
7c96cead34 git_backend: rename git_repo_clone() as it isn't just cloning, propagate error
Since git2::Repository::open() will access to the filesystem, it can technically
fail.
2023-10-04 00:04:24 +09:00
Yuya Nishihara
837dc4f47c git_backend: rewrite remaining git_repo() callers, make it private
While debugging git issues, I often ended up creating a deadlock by adding
debug prints. It's also not obvious that git::export_refs() works even if the
git_repo() has already been locked, whereas git::import_refs() wouldn't. Let's
consolidate lock handling to the backend implementation.
2023-10-04 00:04:24 +09:00
Yuya Nishihara
0d63223dad git_backend: proxy git2::Repository methods to manage lock scope internally
Since git_repo() acquires Mutex, it's super easy to create a deadlock.
2023-10-04 00:04:24 +09:00
Yuya Nishihara
902a43a341 cli: don't list commits abandoned by import/fetch, just print the number
Apparently, it gets too verbose if the remote history is actively rewritten.
Let's summarize the output for now. The plan is to show the list of moved refs
instead of the full list of abandoned commits.
2023-10-03 14:07:56 +09:00
Martin von Zweigbergk
5947387a3d cli_utils: fix a typo in a comment
The codespell GitHub action fails because of the typo. I don't know
why it started failing now. The comment is 8 months old and the
codespell action hasn't been updated in 5 months.
2023-10-02 18:29:25 -07:00
Yuya Nishihara
0fe25575ba cli: ensure first new HEAD is detached
The problem is that the first non-working-copy commit moves the unborn current
branch to that commit, but jj doesn't "export" the moved branch. Therefore,
the next jj invocation notices the "external" ref change, which was actually
made by jj.

I'm not sure why we play nice by setting the "current" HEAD, but I *think* it's
okay to set the "new" HEAD and reset to the same commit to clear Git index.
2023-10-03 00:58:22 +09:00
Yuya Nishihara
480efc1503 cli: add context to checkout/abandon messages triggered by automated git import
Otherwise, it's unclear why "jj status" abandoned commits for example.
2023-10-02 17:31:05 +09:00
Yuya Nishihara
8579bc479f cli: print commits abandoned by git::import_refs() or fetch()
This will probably help to understand why you've got conflicts after fetching.
Maybe we can also report changed local refs.

I think the stats should be redirected to stderr, but we have many other similar
messages printed to stdout. I'll probably fix them all at once later.
2023-10-02 17:31:05 +09:00
Yuya Nishihara
fb08e16238 cli: return early if git::import_some_refs() is noop
I'll make it a bit more verbose if mut_repo().has_changes().
2023-10-02 17:31:05 +09:00
Martin von Zweigbergk
8ec402fc90 cli: report error on bad short-prefixes revset 2023-10-01 11:15:30 -07:00
Martin von Zweigbergk
a6ef3f0b6c cli: make set of immutable commits configurable
This adds a new `revset-aliases.immutable_heads()s` config for
defining the set of immutable commits. The set is defined as the
configured revset, as well as its ancestors, and the root commit
commit (even if the configured set is empty).

This patch also adds enforcement of the config where we already had
checks preventing rewrite of the root commit. The working-copy commit
is implicitly assumed to be writable in most cases. Specifically, we
won't prevent amending the working copy even if the user includes it
in the config but we do prevent `jj edit @` in that case. That seems
good enough to me. Maybe we should emit a warning when the working
copy is in the set of immutable commits.

Maybe we should add support for something more like [Mercurial's
phases](https://wiki.mercurial-scm.org/Phases), which is propagated on
push and pull. There's already some affordance for that in the view
object's `public_heads` field. However, this is simpler, especially
since we can't propagate the phase to Git remotes, and seems like a
good start. Also, it lets you say that commits authored by other users
are immutable, for example.

For now, the functionality is in the CLI library. I'm not sure if we
want to move it into the library crate. I'm leaning towards letting
library users do whatever they want without being restricted by
immutable commits. I do think we should move the functionality into a
future `ui-lib` or `ui-util` crate. That crate would have most of the
functionality in the current `cli_util` module (but in a
non-CLI-specific form).
2023-09-25 15:41:45 -07:00