Commit graph

94 commits

Author SHA1 Message Date
xtqqczze
c49a60e5eb clippy: enable unnecessary_literal_bound lint
Some checks are pending
binaries / Build binary artifacts (push) Waiting to run
website / prerelease-docs-build-deploy (ubuntu-24.04) (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
2025-12-05 17:07:44 +00:00
Scott Taylor
5aa71d59a9 lib: replace MergedTreeId with MergedTree and Merge<TreeId>
After the previous commit, `MergedTree` and `MergedTreeId` are almost
identical, with the only difference being that `MergedTree` is attached
to a `Store` instance. `MergedTreeId` is also equivalent to
`Merge<TreeId>`, since it is just a wrapper around it.

In the future, `MergedTree` might contain additional metadata like
conflict labels. Therefore, I replaced `MergedTreeId` with `MergedTree`
wherever I think it would be required to pass this additional metadata,
or where the additional methods provided by `MergedTree` would be
useful. In any remaining places, I replaced it with `Merge<TreeId>`.

I also renamed some of the `tree_id()` methods to `tree_ids()` for
consistency, since now they return a merge of individual tree IDs
instead of a single "merged tree ID". Similarly, `MergedTree` no longer
has an `id()` method, since tree IDs won't fully identify a `MergedTree`
once it contains additional metadata.
2025-11-08 14:06:58 +00:00
Scott Taylor
79fc20e856 merged_tree: use Merge<TreeId> instead of Merge<Tree>
Currently, creating a `MergedTree` requires reading all of its root
trees from the store. However, this is often not actually required. For
instance, if the only reason to read the trees is to call
`MergedTree::merge`, and the merge is trivial, then there was no need to
read the trees. Changing `MergedTree` to only require a `Merge<TreeId>`
instead of a `Merge<Tree>` will make it possible to avoid reading trees
unnecessarily in these cases.

One benefit of this approach is that `Commit::tree` no longer requires
reading from the store, so it can be made synchronous and infallible,
which simplifies a lot of code.
2025-11-08 14:06:58 +00:00
Martin von Zweigbergk
beda1381bd working_copy: make potentially slow methods async
There's no pressing need, but we should do this eventually.
2025-10-15 03:27:06 +00:00
Yuya Nishihara
46d5555be4 cleanup: leverage trait upcasting, delete as_any*()
This patch also adds .downcast*() wrappers to prevent misuse of as &Any casting.
The compiler wouldn't help detect &Arc<T> as &Any, for example.

https://blog.rust-lang.org/2025/04/03/Rust-1.86.0/#trait-upcasting
2025-09-20 01:22:47 +00:00
Austin Seipp
5b83c9899c cli, lib: convert revset expressions to use Arc over Rc
We want these to be `Send` and `Sync` so we can send them between
threads in our multi-threaded backend. This requires a bunch of subsequent
(but obvious) changes throughout cli and the tests.

Co-authored-by: Benjamin Brittain <ben@ersc.io>
Signed-off-by: Austin Seipp <austin@ersc.io>
Signed-off-by: Austin Seipp <aseipp@pobox.com>
2025-09-05 16:09:44 +00:00
Martin von Zweigbergk
da6c4b61b3 backend: remove unused TreeValue::Conflict and read/write methods
Some checks are pending
binaries / Build binary artifacts (push) Waiting to run
website / prerelease-docs-build-deploy (ubuntu-24.04) (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
We no longer use the `TreeValue::Conflict` constructor or the
`Backend::read_conflict()` and `Backend::write_conflict()` methods.
2025-09-04 16:26:44 +00:00
Ian Wrzesinski
f3d41b1826 working_copy: Move conlfict_marker_styles to TreeState 2025-09-03 00:40:52 +00:00
Yuya Nishihara
a774d79b5d templater: extract non-Core operation methods table 2025-08-21 10:12:45 +00:00
Yuya Nishihara
a8b6c0cba5 templater: rename language-specific operation template types
I'll extract non-"Core" operation types so they can be reused in the commit
templater.
2025-08-21 10:12:45 +00:00
adamnemecek
8a26df2897 cli lib: make use of Self consistent
Mostly done via `cargo clippy --fix -- -A clippy::all -W clippy::use_self`. Added a rule to clippy rules.
2025-07-27 00:12:02 +00:00
Kaiyi Li
74fb5a6096 working copy: pass UserSettings to WorkingCopyFactory
... so that later `TreeState` can query the EOL settings on
construction.
2025-07-17 15:36:28 +00:00
Yuya Nishihara
be094ef76e revset: don't resolve symbol expression to multiple revisions
It's surprising that a symbol expression may be resolved to multiple revisions,
and that's one of the reason we require all: modifier in some places. Let's make
a symbol resolution fail in that case so we can deprecate the all: syntax.

The new error hints are a bit less informative, but I don't want to implement
ad-hoc formatting for resolve_some_revsets_default_single(). The user will have
to review the graph anyway in order to resolve divergence/conflicts.

Closes #5632
2025-07-07 14:11:29 +00:00
Yuya Nishihara
4a9fcb0d15 templater: inline expect_<construct>_with() parsing helpers
There aren't many callers, and it was inconsistent that some callers didn't
attach alias traces to diagnostic messages.

The stripped-down expect_<construct>() functions also attempt to unwrap aliases
for consistency reasons. This is redundant, but should be cheap. If there were
callers who don't need to reinterpret a string literal, they wouldn't have to
use catch_aliases() block at their call sites.
2025-06-30 13:54:57 +00:00
Martin von Zweigbergk
c43ca3c07b address new mismatched_lifetime_syntaxes Clippy lint 2025-06-17 07:40:05 +00:00
Benjamin Brittain
97c7edcafc store: Add Send bounds to the AsyncRead future returned by read_file
This change enables the jj-lib api to be used in multi-threaded executor
contexts.
2025-06-09 21:08:10 +00:00
Martin von Zweigbergk
c90e1396b2 backend: add methods for reading and writing copy objects
This patch implements the methods only in the test backend. That
should enough for us to start implementing diffing and merging on top,
including tests for that functionality. Support in the Git backend can
come once we've seen that the model works.
2025-06-03 01:11:32 +00:00
Martin von Zweigbergk
1d1e0c9e2b backend: make write_file() take an AsyncRead
This is mostly for consistency with `read_file()` at this point. I'm
not sure if we need this for Google in the near future.

For now, I wrapped the file-reading in `local_working_copy.rs` in a
new `BlockingAsyncReader`. We should switch to using async I/O in the
future.
2025-05-22 15:33:33 +00:00
Martin von Zweigbergk
b970939804 backend: make read_file() return a AsyncRead
The `Backend::read_file()` method is async but it returns a `Box<dyn
Read>` and reading from that trait is blocking. That's fine with the
local Git backend but it can be slow for remote backends. For example,
our backend at Google reads file chunks 1 MiB at a time from the
server. What that means is that reading lots of small files
concurrently works fine since the whole file contents are returned by
the first `Read::read()` call (it was fetched when
`Backend::read_file()` was issued). However, when reading files that
are larger than one chunk, we end up blocking on the next
`Read::read()` call. I haven't verified that this actually is a
problem at Google, but fixing this blocking is something we should do
eventually anyway.

This patch makes `Backend::read_file()` return a `Pin<Box<dyn
AsyncRead>>` instead, so implementations can be async in the read part
too.

Since `AsyncRead` is not yet standardized, we have to choose between
the one from `futures` and the one from `tokio`. I went with the one
from `tokio`. I picked that because an earlier version of this patch
used `tokio::fs` for some reads. Then I realized that doing that means
that we have to use a tokio runtime, meaning that we can't safely keep
our existing `pollster::FutureExt::block_on()` calls. If we start
depending on tokio's specific runtime, I think we would first want to
remove all the `block_on()` calls. I'll leave that for later. I think
at this point, we could equally well use `futures::io::AsyncRead`, but
I also don't know if there's a reason to prefer that.
2025-05-20 13:23:36 +00:00
Martin von Zweigbergk
275504235b cli: replace ExitCode by u8
I'd like to make the internal `jj` binary at Google log the exit code,
but `ExitCode` doesn't seem to provide any way of getting the numeric
code out of it. This patch therefore replaces `ExitCode` by `u8` and
lets the `main()` function convert it to `ExitCode`. It's a bit
unfortunate but I don't see a better solution. It doesn't seem worth
it to create our own newtype for it.
2025-05-17 05:45:59 +00:00
Yuya Nishihara
f5c36d5420 templater: replace remainders of P::wrap_<type>(), remove old wrap_<type> fns 2025-05-10 10:04:30 +00:00
Yuya Nishihara
780f9e547d templater: call property wrap_() functions directly, delete old forwarding fns
This patch replaces single-char L type aliases with P, and renames the L aliases
where that makes sense. Many of the P aliases will be removed later by
introducing generic wrap<T>() trait.
2025-05-05 01:16:41 +00:00
Yuya Nishihara
b96924d17f templater: convert property to trait object by caller
I'm trying to refactor property wrapping functions, and noticed that it's odd
that .wrap_<property>() does boxing internally whereas .wrap_template() doesn't.

Also, it sometimes makes sense to turn property into trait object earlier. For
example, we can deduplicate L::wrap_boolean() in build_binary_operation().
2025-05-01 00:33:59 +00:00
Yuya Nishihara
3f5f872204 view: rename workspace "id" to "name"
This matches the current implementation.
2025-03-31 03:39:29 +00:00
Yuya Nishihara
e66c545438 view: replace WorkspaceId by string-like newtypes
I think this makes more sense because WorkspaceId is currently a human-readable
name. In error/status messages, workspace names are now printed in revset
syntax.

New WorkspaceId types do not implement Default. It would be weird if string-like
type had non-empty Default::default(). The DEFAULT constant is provided instead.
2025-03-31 03:39:29 +00:00
Yuya Nishihara
ffad6fe96f revset: extract internal context struct from RevsetParseContext
This allows callers to mutate RevsetParseContext if needed.

RevsetParseContext was changed to an opaque struct at 4e0abf0631 "revset: make
RevsetParseContext opaque." I think the intent there was to hide implementation
details from revset extension functions. This is now achieved by opaque
LoweringContext.

Another reason of this change is that aliases_map is no longer needed when
transforming AST to UserRevsetExpression.
2025-03-26 13:03:41 +00:00
Ilya Grigoriev
acaedc3382 cleanup: enable unused_trait_names clippy lint and run clippy --fix 2025-03-16 00:35:56 +00:00
Yuya Nishihara
127f7e23ac examples: use settings_for_new_workspace() when initializing workspace
Spotted while replacing callers of CommandHelper::settings().
2025-01-06 21:15:28 +09:00
Yuya Nishihara
cff73841ed repo: remove &UserSettings argument from new/rewrite_commit(), use self.settings 2024-12-31 10:51:57 +09:00
Scott Taylor
9591523db4 gitignore: add more detail to errors on invalid pattern 2024-12-16 18:49:48 -06:00
Yuya Nishihara
f4fdc19d9e working_copy: plumbing to propagate untracked paths to caller 2024-12-11 20:19:51 +09:00
Scott Taylor
e5cb9f94f6 conflicts: add "ui.conflict-marker-style" config
Adds a new "ui.conflict-marker-style" config option. The "diff" option
is the default jj-style conflict markers with a snapshot and a series of
diffs to apply to the snapshot. New conflict marker style options will
be added in later commits.

The majority of the changes in this commit are from passing the config
option down to the code that materializes the conflicts.

Example of "diff" conflict markers:

```
<<<<<<< Conflict 1 of 1
+++++++ Contents of side #1
fn example(word: String) {
    println!("word is {word}");
%%%%%%% Changes from base to side #2
-fn example(w: String) {
+fn example(w: &str) {
     println!("word is {w}");
>>>>>>> Conflict 1 of 1 ends
}
```
2024-11-23 08:28:47 -06:00
Yuya Nishihara
62e4943c04 revset: reorganize expression resolution/evaluation methods
Both user and programmatic expressions use the same .evaluate() function now.
optimize() is applied globally after symbol resolution. The order shouldn't
matter, but it might be nicer because union of commit refs could be rewritten
to a single Commits(Vec<CommitId>) node.
2024-11-08 10:34:02 +09:00
Yuya Nishihara
e55d03a2ee revset: introduce type-safe user/resolved expression states
This helps add library API that takes resolved revset expressions. For example,
"jj absorb" will first compute annotation within a user-specified ancestor range
such as "mutable()". Because the range expression may contain symbols, it should
be resolved by caller.

There are two ideas to check resolution state at compile time:
<https://github.com/martinvonz/jj/pull/4374>

 a. add RevsetExpressionWrapper<PhantomState> and guarantee inner tree
    consistency at public API boundary
 b. parameterize RevsetExpression variant types in a way that invalid variants
    can never be constructed

(a) is nice if we want to combine "resolved" and "unresolved" expressions. The
inner expression types are the same, so we can just calculate new state as
Resolved & Unresolved = Unresolved. (b) is stricter as the compiler can
guarantee invariants. This patch implements (b) because there are no existing
callers who need to construct "resolved" expression and convert it to "user"
expression.

.evaluate_programmatic() now requires that the expression is resolved.
2024-11-08 09:56:33 +09:00
dploch
49e9003c4e revset: allow iterators to return evaluation errors
Custom backends may rely on networking or other unreliable implementations to support revsets, this change allows them to return errors cleanly instead of panicking.

For simplicity, only the public-facing Revset and RevsetGraph types are changed in this commit; the internal revset engine remains mostly unchanged and error-free since it cannot generally produce errors.
2024-10-18 17:09:35 -04:00
Yuya Nishihara
11286b3072 templater: pass diagnostics receiver around 2024-09-23 07:07:07 +09:00
Yuya Nishihara
8b1760ca5d revset: pass diagnostics receiver around
Stacking at AliasExpanded node looks wonky. If we migrate error handling to
Diagnostics API, it might make sense to remove AliasExpanded node and add
node.aliases: vec![(id, span), ..] field instead.

Some closure arguments are inlined in order to help type inference.
2024-09-23 07:07:07 +09:00
Yuya Nishihara
4533e81957 cli: pass &Ui to parse fileset/revset/template functions
Deprecation warnings will be printed there. auto_tracking_matcher(ui) could
be cached, but there aren't many callers right now, so it should be okay to
parse and emit warnings for each invocation. Other than that, the changes are
straightforward.
2024-09-20 23:01:12 +09:00
Kevin Liao
412ef36259 cli: Support renaming workspaces
fixes #4342
2024-09-16 19:35:36 -07:00
Yuya Nishihara
47307556dd working_copy: pass SnapshotOptions by reference
Though SnapshotOptions can be cheaply cloned, it doesn't make much sense that
snapshot() consumes a settings-like object.
2024-09-08 04:51:21 +09:00
Martin von Zweigbergk
8d090628c3 transaction: rename mut_repo() to idiomatic repo_mut()
We had both `repo()` and `mut_repo()` on `Transaction` and I think it
was easy to get confused and think that the former returned a
`&ReadonlyRepo` but both of them actually return a reference to
`MutableRepo` (the latter obviously returns a mutable reference). I
hope that renaming to the more idiomatic `repo_mut()` will help
clarify.

We could instead have renamed them to `mut_repo()` and
`mut_repo_mut()` but that seemed unnecessarily long. It would better
match the `mut_repo` variables we typically use, though.
2024-09-07 10:51:43 -07:00
Martin von Zweigbergk
8eb3d85b1c backend: make write methods async
This doesn't provide any benefit yet bit I think we've known for a
while that we want to make the backend write methods async. It's just
not been important to Google because we have the local daemon process
that makes our writes pretty fast. Regardless, this first commit just
changes the API and all callers immediately block for now, so it won't
help even on slow backends.
2024-09-04 18:34:11 -07:00
Yuya Nishihara
87fb169266 cleanup: remove redundant ::{self} from use declarations 2024-08-23 13:05:27 +09:00
Matt Kulukundis
8ead72e99f formatting only: switch to Item level import ganularity 2024-08-22 14:52:54 -04:00
Martin von Zweigbergk
749a284354 working_copy: delete path() method from trait
We don't currently use the `path()` method. Not all working copies
even have a relevant path. For example, working copies on Google's
server don't.
2024-08-16 16:55:14 -07:00
Matt Kulukundis
ee6b922144 copy-tracking: create CopyRecordMap and add it to diff summaries 2024-08-11 17:01:45 -04:00
Matt Kulukundis
e667a2b403 copy-tracking: adjust backend signature
- use a single commit instead of an array of them.  This simplifies the
  implementation.  A higher level api can wrap this when an array of
  commits is desired and those semantics are figured out.
- since this API is directly 1-1 on parents, there are no conflicts
- if we introduce a higher level API that handles lists of commits, we
  may need to restore the conflict/resolved distinction, but for now
  simplify
2024-08-11 17:01:45 -04:00
Yuya Nishihara
3f05d065b5 cli: uncapitalize op description of "workspace add" and custom command example
That's our convention.
2024-07-24 18:06:09 +09:00
Matt Kulukundis
dab8a29683 copy-tracking: stub get_copy_records
- add the method and types for all backends
2024-07-03 20:26:30 -04:00
Yuya Nishihara
9613ec4f82 revset: drop Eq/PartialEq from RevsetExpression and related types
It was convenient that expression nodes can be compared in tests, but no
equivalence property is needed at runtime. Let's remove Eq/PartialEq to
simplify the extension support.
2024-06-28 10:28:51 +09:00