Commit Graph

194 Commits

Author SHA1 Message Date
Josh Steadmon
671d99f497 backend: note that get_related_copies() should be deterministic
We only specify a partial ordering for the histories returned by
`Backend::get_related_copies`. However, to avoid inconsistent behavior
and flaky tests, we would like the ordering to be deterministic. Note
this in the doc comment, and make the TestBackend deterministic.
2026-06-12 15:58:15 +00:00
OlshaMB
0be16038b9 lib: Make tokio optional by replacing tokio traits with future traits
This enables having custom async runtimes, without having to depend on a huge tokio dependency, just for traits.

tokio is still enabled in testing, and if watchman feature is enabled.

Commit replaces `AsyncRead(Ext)` from tokio to futures(which is already a dependency), as a sideeffect it uses `Cursor` from futures.

This commit also gets rid of `BlockingAsyncReader` by using futures's `AllowStdIo`
2026-05-10 13:42:47 +00:00
Martin von Zweigbergk
22b04970fb working_copy: make start_mutation() async
This method may reasonably need to do slow I/O, and the implementation
for Google's VFS indeed does that, so it should be async.
2026-05-04 14:00:31 +00:00
Ilya Grigoriev
419632a9cf tests: .block_on().unwrap() with .block_on()? in tests using TestResult from parent commit
This commit should be comparable with https://github.com/jj-vcs/jj/pull/9050

As of this writing, this replaced all but out of 1053 instances of
`.block().unwrap()`. The remaining ones (as counted by AI):

```

┌──────────────────┬───────┬────────────────────────────────────────────────────┐
  │     Category     │ Count │                   Could convert?
│

├──────────────────┼───────┼────────────────────────────────────────────────────┤
  │ testutils        │ 20    │ No — return concrete types, would cascade to
│
  │ helpers          │       │ hundreds of callers across all test files
│

├──────────────────┼───────┼────────────────────────────────────────────────────┤
  │ Closures         │ 53    │ No — closures return () or concrete values
│

├──────────────────┼───────┼────────────────────────────────────────────────────┤
  │ Test helpers     │ 22    │ Technically yes, but adds ~70 ? at call sites
to   │
  │                  │       │ save 22 unwraps
│

├──────────────────┼───────┼────────────────────────────────────────────────────┤
  │ Non-convertible  │ 4     │ No — CommandError (2), Pin<Box<dyn Future>>
(1),   │
  │                  │       │ closure in test_matrix (1)
│

└──────────────────┴───────┴────────────────────────────────────────────────────┘
```
2026-03-23 19:30:08 +00:00
Gaëtan Lehmann
088c4d161b testutils: use eyre::Result as TestResult 2026-03-23 19:30:08 +00:00
Martin von Zweigbergk
bacef10d0b cleanup: use BoxStream and .boxed() more
This was mainly to reduce type complexity by using `BoxStream`. The
documentation for that type says that's its often created by calling
`.boxed()`, so I did that too.
2026-03-16 13:27:36 +00:00
Josh Steadmon
e91fdaa683 testutils: add helper functions for manipulating copy history 2026-03-11 22:22:11 +00:00
Josh Steadmon
077b27efd3 backend: return CopyId along with CopyHistory
Constructing a CopyId for a given CopyHistory is backend-specific.
However, most methods of getting a CopyHistory require you to have the
CopyId already, so it's usually not necessary to create an ID from
scratch.

`get_related_copies()` in the Backend trait is an exception though.
Since it's not widely in use yet, let's change it to also return the
CopyId for each related CopyHistory.
2026-03-11 22:22:11 +00:00
Benjamin Tan
1b5b4512e9 store: remove sync version of get_tree 2026-03-08 16:43:44 +00:00
Benjamin Tan
d51e0b7af7 tree_builder: convert some functions to async 2026-03-05 20:45:43 +00:00
Benjamin Tan
1871f4b5ea LockedWorkspace: make LockedWorkspace::finish async 2026-03-05 20:45:43 +00:00
Benjamin Tan
6ab12e5967 workspace: convert functions to async 2026-02-22 04:53:22 +00:00
Benjamin Tan
d44a92efb6 transaction: convert functions to async 2026-02-22 04:53:22 +00:00
Benjamin Tan
e59480cbef ReadonlyRepo: convert functions to async 2026-02-21 19:20:31 +00:00
Benjamin Tan
bc66098372 RepoLoader: convert functions to async 2026-02-21 19:20:31 +00:00
Benjamin Tan
a3f180215a MutableRepo: convert functions to async 2026-02-21 19:20:31 +00:00
Martin von Zweigbergk
5b2bf8736c commit_builder: make write() async 2026-02-15 17:12:05 +00:00
Martin von Zweigbergk
4766312253 lib tests: add shortcut for CommitBuilder::write().unwrap()
I'm about to make `CommitBuilder::write()` async. This will help
reduce wrapping due to chaining.
2026-02-15 17:12:05 +00:00
Kaiyi Li
c21eeb68c4 testutils: 3 way merge tree builder and copy id setter
* Add a utility type `TestThreeWayMergeTreeBuilder` to create a 3-way
merge tree with convenience.
* Add `TestTreeFileEntryBuilder::copy_id` to allow customize the CopyId
  of a file in the tree.
2026-02-01 23:47:15 +00:00
Martin von Zweigbergk
a0ecd220b9 merged_tree: rename trees_async() to trees() 2026-01-03 22:51:08 +00:00
Martin von Zweigbergk
50420c123e merged_tree: inline & delete sync version of trees() 2026-01-03 22:51:08 +00:00
Kaiyi Li
f4bef4a539 test: get rid of unexpected git hint message
Set the git `init.defaultBranch` config to avoid the following git hint
message that breaks the test.

────────────┬──────────────────────────────────────────────────────────────────
    1     1 │ ------- stderr -------
    2     2 │ Cloning into '$TEST_ENV/repo/sub'...
          3 │+hint: Using 'master' as the name for the initial branch. This default branch name
          4 │+hint: is subject to change. To configure the initial branch name to use in all
          5 │+hint: of your new repositories, which will suppress this warning, call:
          6 │+hint:
          7 │+hint:     git config --global init.defaultBranch <name>
          8 │+hint:
          9 │+hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
         10 │+hint: 'development'. The just-created branch can be renamed via this command:
         11 │+hint:
         12 │+hint:     git branch -m <name>
    3    13 │ done.
    4    14 │ [EOF]
────────────┴──────────────────────────────────────────────────────────────────
2026-01-01 16:20:21 +00:00
Yuya Nishihara
3890c28493 merge: implement IntoIterator for references of Merge<T>
It seemed odd that owned values can be looped over with "for", but borrowed
values can't.
2025-12-09 23:28:23 +00:00
Scott Taylor
2e18f59bc9 backend: add conflict labels to Commit 2025-12-09 14:23:43 +00:00
Scott Taylor
d4668bf3fc merged_tree: add conflict labels to MergedTree 2025-12-09 14:23:43 +00:00
xtqqczze
6d8bf975f6 rustc_lint: enable redundant-imports lint
https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#redundant-imports
2025-12-09 13:30:44 +00:00
xtqqczze
c49a60e5eb clippy: enable unnecessary_literal_bound lint 2025-12-05 17:07:44 +00:00
Mitchell Skaggs
2af8bf94a3 testutils: add check for strict UTF-8 filesystems
`test_init_load_non_utf8_path` and
`test_init_additional_workspace_non_utf8_path` now early-return on
strict UTF-8 filesystems because there's no way to report a test as
"skipped" at runtime.

Closes https://github.com/jj-vcs/jj/issues/8118
2025-11-27 00:36:39 +00:00
Lucio Franco
d9f2772988 cli: add jj file track --include-ignored flag
This adds support for tracking ignored and oversized files with `jj file track`.

Previously, `jj file track` would silently fail to track files that were ignored by
`.gitignore` or larger than `snapshot.max-new-file-size`. This commit introduces an
`--include-ignored` flag that allows users to explicitly track these files.

## Implementation

Added a `force_tracking_matcher` field to `SnapshotOptions` that overrides ignore rules
and size limits. When `--include-ignored` is specified, the file pattern matcher is
passed as `force_tracking_matcher`, allowing three checks in `FileSnapshotter` to bypass
their usual restrictions for directory ignores, file ignores, and file size limits.

## Tests

- `test_track_ignored_with_flag`: Verifies `.gitignore`d files can be tracked
- `test_track_large_file_with_flag`: Verifies oversized files can be tracked
- `test_track_ignored_directory`: Verifies ignored directories can be tracked recursively

# Checklist

If applicable:

- [ ] I have updated `CHANGELOG.md`
- [x] I have updated the documentation (`README.md`, `docs/`, `demos/`)
- [ ] I have updated the config schema (`cli/src/config-schema.json`)
- [x] I have added/updated tests to cover my changes
2025-11-14 03:14:37 +00:00
Scott Taylor
da1921ead5 testutils: dump_tree: print contents of conflicted trees
Previously, `assert_tree_eq!` would give a confusing panic message if
one of the trees had a conflict.
2025-11-09 17:48:25 +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
d8acbec3fc dag_walk: propagate error when cycle is detected
A sibling team of my team sometimes runs into panics caused by cycles
in the commit graph. This patch removes the panics from `dag_walk` by
having all the callers pass in a `cycle_fn`. For now, the callers
panic instead.
2025-10-27 14:16:34 +00:00
Scott Taylor
141832414a backend: remove MergedTreeId::Legacy variant
I'm planning to try to add conflict labels to `MergedTree` and
`MergedTreeId`, and it will be easier to add them if both are structs
with similar methods. Since we don't support reading/writing legacy
conflicts anymore (as far as I'm aware), I think it should be safe to
delete the `MergedTreeId::Legacy` variant now.
2025-10-19 13:14:27 +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
Yuya Nishihara
ccd1373f1b working_copy: move SnapshotOptions::empty_for_test() to testutils 2025-09-14 03:55:09 +00:00
Martin von Zweigbergk
da6c4b61b3 backend: remove unused TreeValue::Conflict and read/write methods
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
Yuya Nishihara
7e80eb4dfa cargo: bump toml_edit to 0.23.3
Also updated deprecated ImDocument references to Document.
2025-08-23 03:46:11 +00:00
Martin von Zweigbergk
28562f1b10 tests: remove CommitGraphBuilder
The `CommitGraphBuilder` type doesn't seem to carry its weight
anymore.
2025-07-31 04:56:34 +00:00
Martin von Zweigbergk
ca6edfaab0 tests: add a helper for writing random commit with given parents 2025-07-31 04:56:34 +00:00
Austin Seipp
ba24140f1d cli, lib: move to Rust 2024 language edition
This applies a `cargo fmt` and fixes clippy lints to keep the build
properly working.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
2025-07-28 17:05:41 +00:00
Austin Seipp
99ab453790 testutils: add + use<> bounds for impl Strategy
Signed-off-by: Austin Seipp <aseipp@pobox.com>
2025-07-28 17:05:41 +00:00
Austin Seipp
bee574354b testutils: set_env is unsafe in Rust 2024
`set_env` is, for various reasons, fundamentally unsafe on approximately
~all modern unicies, and seems like it will never ever be fixed. The
long and short of this is that it will result in segfaults or UB. Rust
2024 therefore marks this function (correctly) as `unsafe`.

The correct solution for 98% of use cases is just to use `envp` during
calls to `execv`, but for our simple cases here of making Git hermetic
there shouldn't be an issue, and a larger refactoring would be needed
for an alternative anyway.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
2025-07-28 17:05:41 +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
Martin von Zweigbergk
721daef0b4 store: inline tree_builder() function to callers
`Store::tree_builder()` returns a `TreeBuilder`. Almost all callers
should be using the `MergedTreeBuilder` these days. This patch
therefore removes `tree_builder()` to reduce the risk of accidentally
using it.
2025-07-18 21:36:13 +00:00
Kaiyi Li
f1f1556731 local working copy: add support for EOL conversion 2025-07-17 15:36:28 +00:00
Martin von Zweigbergk
5d35eadd4e tests: make TestBackend async for more realistic testing
The `TestBackend` methods currently return their data immediately (on
the first poll), which means that if multiple futures are created and
then they're polled "concurrently", they will always return their data
in the order they're being polled. That leads to poor testing of
algortihms that poll futures concurrently, such as `TreeDiffStream`.

This patch makes `TestBackend` spawn async work to run in a tokio
runtime instead. That's enough to show a bug I introduced with my
recent refactoring of `TreeDiffStream`, except that it's also covered
up by the caching we do in `Store`. I'll fix the bug and update tests
to work around the caching next.

This slows down the jj-lib tests from 2.8 s to 3.1 s. I don't think
that matter much, given that the jj-cli tests takes > 30 s.

I tried to add a small `tokio::time::sleep()` (random up to 5 ms) but
that slowed down the property-based tests of the diff editor very
significantly (took over a minute). Maybe we could have two different
kinds of test backend or maybe make the sleep configurable in some
way. We can improve that later. The async-ness added in this patch is
sufficient for catching the diff-stream bug.
2025-07-14 16:09:41 +00:00
Ilya Grigoriev
6323764f69 lib: add rustversion, turn off a clippy lint in nightly in tests
This turns off the `clippy::cloned_ref_to_slice_refs` lint in some tests
and fixes it in others, for Rust 1.89+. This seems to make `cargo clippy
--workspace --all-targets --all-features` work in stable, beta, and
nightly (1.89).

This depends on the `rustversion` crate. Other than that, it's based on
Austin's https://github.com/jj-vcs/jj/pull/6705.

Co-authored-by:  Austin Seipp <aseipp@pobox.com>
2025-06-24 01:01:25 +00:00
Jonas Greitemann
94ba95bb4c merge-tools builtin: add property-based testing
This adds the proptest crate for property-based testing as well as the
proptest-state-machine crate as direct dev dependencies of jj-cli and as
dependencies of the internal testutils crate. 

Within testutils, a `proptest` module provides a reference state
machine which models the working copy as a map from path to `DirEntry`.
Directories are not represented explicitly, but are implicit in the
ancestors of entries.

The possible transitions of this state machine are for now limited to
the creation of new files (including replacements of existing files
or directories) and a `Commit` operation which the SUT can use to
snapshot a reference state. Additional transitions (moving files,
modifying file contents incrementally, ...) and states (symlinks,
submodules, conflicts, ...) may be added in the future.

This reference state machine is then applied to the builtin merge-tool's
test suite:
- The initial state is always an empty root directory.
- The `Commit` operation creates `MergedTree` from the current state.
- Each step of the way, the same test logic as in the manual
  `test_edit_diff_builtin*` tests is run to check that splitting off
  none or all of the changes results in the left or right tree,
  respectively. The "right" tree corresponds to the current state,
  whereas the "left" tree refers to the last "committed" tree.

Co-authored-by: Waleed Khan <me@waleedkhan.name>
2025-06-18 20:45:56 +00:00