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.
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`
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)
│
└──────────────────┴───────┴────────────────────────────────────────────────────┘
```
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.
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.
* 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.
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]
────────────┴──────────────────────────────────────────────────────────────────
`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
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
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.
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.
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.
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.
`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>
`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.
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.
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>
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>