Commit graph

1343 commits

Author SHA1 Message Date
Kaiyi Li
eb1f72a0c9 file_util: fix broken symlink on Windows
... due to using incorrect separators.

Fix #8185.
2025-12-05 03:43:34 +00:00
Ian Wrzesinski
b8cfd972ed lib/tests: Add basic executable bit tests on Unix 2025-12-04 17:32:40 +00:00
Yuya Nishihara
36143b093e git: add native support for negative fetch patterns
The default patterns are still saved to and loaded from .git/config. Maybe we
can add default fetch patterns to jj's configuration, but I'm not sure whether
we should deprecate .git/config fallback.
2025-12-03 08:12:58 +00:00
Yuya Nishihara
8615362689 git: compile both positive/negative branch patterns to StringMatcher
I also renamed "branch" to "bookmark" because we call refs as "bookmark"s where
the matcher is used.
2025-12-03 07:32:25 +00:00
Yuya Nishihara
1d897341cc git: parse negative refspecs to branch patterns
We'll need negative patterns to exclude them when importing remote refs from Git
repository.
2025-12-03 07:32:25 +00:00
Matt Stark
668a034e08 working-copy: Ensure sub-repos are not tracked.
If a submodule was created in a commit C on a remote repo, switching from any
commit after C to any commit before C (eg. `jj new C-`) will result in jj
starting to track the files introduced in the submodule.

This issue has popped up very frequently for chromium developers, who
get issues when attempting to check out an older version of chromium.

Fixes #4349
2025-12-02 23:20:34 +00:00
Mitchell Skaggs
2af8bf94a3 testutils: add check for strict UTF-8 filesystems
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
`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
Lander Brandt
7e42895b59 lib: substantially reduce syscalls when attempting to create dirs
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
After filing https://github.com/jj-vcs/jj/issues/7685 I ran some perf traces to try to understand just what was taking so long during these slow operations. The changes in this PR reduces clone time for my large repo from about 10 minutes to 4m30s.

You can see my thought process in the comments of the above task but to summarize:

During checkout we check files/directories being created to ensure that we are not attempting to write to a reserved directory (`.jj/`, `.git/`). `same_file::is_same_file()` is an expensive check that invokes _at least 4_ syscalls when called in a naive manner (`open()` and `close()` for each path -- plus possibly more for getting file info? I haven't counted).

There are a few optimization gaps here that are causing significant slowdowns. The following checklist reflects what I've optimized in this PR, and what still remains:

- [x] `create_parent_dirs` will be called for each file/directory and for each parent dir in a path **try to create it and check if the dir is an illegal name via `reject_reserved_existing_path()`**. There is no caching of directories which have already been created.
- [ ] `reject_reserved_existing` calls `same_file::is_same_file()` in a loop for all reserved names, but the path which _has maybe been created_ isn't going to change, so its handle could be cached.
- [ ] `can_create_new_file` attempts to create the file then just uses the result as an indicator of whether or not the file is created. However, since we _have a `File`_ that `File` can be directly converted to a `same_file::Handle` and avoid a syscall that currently occurs when converting the `Path` to a `same_file::Handle`.
- [ ] `can_create_new_file` deletes the file immediately after. There's probably an opportunity here to **not** delete the file and re-use it for file write operations.
- [ ] Say we have 1000 files in `foo/`. For each file that's written, `reject_reserved_existing` is going to make at least `RESERVED_DIR_NAMES.len() * 1000` syscalls constructing `foo/{reserved_dir_name}` paths, testing their existence, etc. Maybe `jj` might create this dir? But I don't think that should ever happen -- so why not cache the handle **if** it's created and use a lookup table in `reject_reserved_existing` to only conduct these types of checks if the handle is resolved? Or alternatively cache that the file _does not_ exist after the first check.

Here are some perf traces of running a `jj git clone` of my large repo before:

Release: https://share.firefox.dev/4oiSTBw
Debug: https://share.firefox.dev/4qmJBX1

And after:

Release: https://share.firefox.dev/4nK66mH
Debug: https://share.firefox.dev/470W1ed
2025-11-26 02:30:31 +00:00
Yuya Nishihara
c93682f218 revset: parameterize default string pattern kind, add config knob
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
Glob patterns will be enabled by default globally. Since this will be a big
breaking change in revsets, this patch adds a config knob to turn the new
default on/off.
2025-11-24 01:39:32 +00:00
Yuya Nishihara
3b37ed102e tests: specify string pattern prefix, use subject(glob:_) accordingly
Deprecation warnings will be emitted for default "substring:" patterns. This
change will suppress them. Since "glob:" will be the new default, I made these
tests use "glob:" when both "exact:" and "glob:" work.

Tests for the revset filter functions aren't updated.
2025-11-24 01:39:32 +00:00
Yuya Nishihara
4d296a7f9f str_util: map glob pattern with no meta character to exact pattern
Suppose the default is changed to "glob:", literal strings would be parsed by
glob() function. It's still better to treat trivial strings as "exact" patterns.

str_util::is_glob_char() includes backslash unconditionally because we enable
backslash escapes in string patterns.
2025-11-24 01:39:32 +00:00
Yuya Nishihara
a7a4ed033a git: move GitSettings out of settings module
This type wouldn't be needed if the "git" feature is disabled.
2025-11-21 15:04:09 +00:00
Remo Senekowitsch
e4d45dda34 tests: replace auto-local-bookmark with auto-track-bookmarks
This paves the way to deprecate `git.auto-local-bookmark` without
adding lots of deprecation warnings to test output snapshots.

The behavior of some tests is slightly changed, because
auto-track-bookmarks also tracks bookmarks that were created locally.
I think it just shows up in output snapshots as absent-tracked
bookmarks, without affecting what the test is about.
2025-11-21 05:15:55 +00:00
Scott Taylor
da1921ead5 testutils: dump_tree: print contents of conflicted trees
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
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
Scott Taylor
f08e50a21f conflicts: add "diff-experimental" conflict marker style
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
#7917
2025-11-05 00:00:58 +00:00
Martin von Zweigbergk
b409aa3189 colocation: rename from "colocated repo" to "colocated workspace"
Colocation is about sharing the working copy between jj and git. It's
less important where the repo is stored. I therefore think we should
not call it "colocated repo". I considered renaming it to "colocated
working copy" but that sounded awkward in many places because we often
talk about the whole workspace (repo + working copy), so "In colocated
workspaces with a very large number of branches or other refs" sounds
better than "In colocated working copies with a very large number of
branches or other refs".

Once we support colocate workspaces in non-main Git worktrees, I think
this rename will be even more relevant because then all those
workspaces share the same repo but only some of them may be colocated.
2025-11-03 16:53:26 +00:00
Yuya Nishihara
d6b5530513 revset: do not ignore "git" remote if user pattern is specified
Since we can now express the default pattern as `remote=~exact:"git"`, we can
unblock queries matching the "git" remote.
2025-10-31 00:37:50 +00:00
Yuya Nishihara
626e5b29a6 revset: parameterize special "git" remote that is ignored by default
The default remote parameter of remote_bookmarks() will be derived from this
parameter. It doesn't make sense to exclude @git bookmarks if the backend isn't
Git. It's also nice that parsing tests don't depend on the feature flag.
2025-10-31 00:37:50 +00:00
Yuya Nishihara
f7256f611c revset: parse string patterns into StringExpression
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
A typical use case is to query bookmarked revisions ignoring auto-generated
bookmarks. `bookmarks() ~ bookmarks(x)` doesn't work because a revision may have
multiple bookmarks. It's also nice that we can document the default of
`remote_bookmarks()` as `remote_bookmarks(remote=~exact:"git")`.

Closes #7665
2025-10-29 23:59:58 +00:00
Yuya Nishihara
843b45b7cb str_util: rename StringPattern::everything() to all()
I'm going to add AST type for compound string match expressions, and this type
will be similar to Revset/FilesetExpression which implement all().
2025-10-29 11:19:42 +00:00
Brian Schroeder
7810926c35 index: make Index::is_ancestor fallible
This is part of a series of changes to make most methods on index traits
(i.e. `ChangeIdIndex`, `MutableIndex`, `ReadonlyIndex`, `Index`)
fallible. This will enable networked implementations of these traits,
which may produce I/O errors during operation. See #7825 for more
information.

- Introduced a few more instances of the existing anti-pattern, `TODO:
  indexing error shouldn't be a "BackendError"`. We're tracking this
  known issue in #7849.
- Converted `MutableRepo::merge_view` to return a `RepoLoaderError`
  instead of a `BackendError`. The only caller, `MutableRepo::merge`,
  already returns a `RepoLoaderError`.
- Added three "`fallible_`" iterator helpers to reduce the amount of
  noise at `is_ancestor` call sites due to the method now being
  fallible. Using these helpers seem to produce code that's a little
  more readable than using `process_results` from itertools. One
  consideration in this trade-off is that these helpers do not
  themselves return iterators: if we find that we need more support for
  fallible combinators mid-"chain" of iterator combinators, we might
  either want to use `process_results` only in those cases, or switch to
  use of `process_results` across the board (in lieu of these new
  helpers).
2025-10-28 13:47:44 +00:00
Scott Taylor
a16c89f16e conflicts: render exactly one snapshot in "diff" marker style
Although rare, it would be very confusing to a user if they encountered
a conflict with a `-------` marker while using the "diff" style. This
addresses a TODO in the test.
2025-10-28 12:43:08 +00:00
Martin von Zweigbergk
b62438e398 repo: propagate error when there's a cycle in parent_mapping
We were sometimes seeing crashes at Google when a commit was rewritten
very quickly without any changes. This should prevent the crashes and
return an error to the user instead.
2025-10-27 14:16:34 +00:00
Brian Schroeder
b8fa9ecf9c index: make Index::has_id fallible
This is part of a series of changes to make most methods on index traits
(i.e. `ChangeIdIndex`, `MutableIndex`, `ReadonlyIndex`, `Index`)
fallible. This will enable networked implementations of these traits,
which may produce I/O errors during operation. See #7825 for more
information.
2025-10-25 18:05:13 +00:00
Yuya Nishihara
5f40f62494 cleanup: remove redundant + use<'_> after migrating to 2024 edition
AliasFunctionOverloads::arities() doesn't need to capture &self, but it's not
important to describe the lifetime precisely here.
2025-10-25 02:09:31 +00:00
Brian Schroeder
159fb829d5 index: make Index::resolve_commit_id_prefix fallible
This is part of a series of changes to make most methods on index traits
(i.e. `ChangeIdIndex`, `MutableIndex`, `ReadonlyIndex`, `Index`)
fallible. This will enable networked implementations of these traits,
which may produce I/O errors during operation. See #7825 for more
information.
2025-10-24 10:51:56 +00:00
Brian Schroeder
385fb064b9 index: make Index::shortest_unique_commit_id_prefix_len fallible
This is part of a series of changes to make most methods on index traits
(i.e. `ChangeIdIndex`, `MutableIndex`, `ReadonlyIndex`, `Index`)
fallible. This will enable networked implementations of these traits,
which may produce I/O errors during operation. See #7825 for more
information.
2025-10-24 10:51:56 +00:00
Brian Schroeder
c70f9b5b3f index: make ChangeIdIndex::shortest_unique_prefix_len fallible
This is part of a series of changes to make most methods on index traits
(i.e. `ChangeIdIndex`, `MutableIndex`, `ReadonlyIndex`, `Index`)
fallible. This will enable networked implementations of these traits,
which can produce I/O errors during operation. See #7825 for more
information.
2025-10-23 15:28:33 +00:00
Brian Schroeder
5468bb49d3 index: make ChangeIdIndex::resolve_prefix fallible
This is part of a series of changes to make most methods on index traits
(i.e. `ChangeIdIndex`, `MutableIndex`, `ReadonlyIndex`, `Index`)
fallible. This will enable networked implementations of these traits,
which can produce I/O errors during operation. See #7825 for more
information.
2025-10-23 15:28:33 +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
Benjamin Brittain
3881bd52d7 op_store: convert OpStore trait to be async
This is primarily for consistency with the other storage traits.
2025-10-19 05:46:00 +00:00
Owen Brooks
f88b0d8093 cli: git clone: add --branch option
When cloning with the branch option:
- Only the specified branch will be fetched
- The trunk alias is only set if the specified branch happens to be the default branch
- The clone fails if the branch does not exist in the remote
2025-10-19 05:14:11 +00:00
Owen Brooks
e98e2e58c8 cli: Add RefExpansionError for expand_fetch_refspecs 2025-10-19 05:14:11 +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
82dd14fd85 git: ensure RemoteView is created for remote with no existing refs
This will help "jj bookmark track" know whether absent remote ref can be created
for the specified remote. "jj bookmark" subcommands shouldn't depend on
gix::Repository API.
2025-10-15 01:52:19 +00:00
Yuya Nishihara
429fec1ae3 git: export tag changes
Although we don't have "jj git tag set"/"delete" commands, this fixes weird undo
behavior #6325. The discussion in #6325 is derailed, but there would be another
issue for the "abandon unreachable" behavior.

Fixes #6325
2025-10-15 01:31:16 +00:00
Yuya Nishihara
26bbda9d73 git: on import, do not ignore absent tracked remote refs
Since "tracked" state doesn't exist in Git, git::import_refs() should ignore
absent->absent "changes". git::export_refs() just works because it compares only
ref targets.
2025-10-11 11:59:28 +00:00
Yuya Nishihara
122acd5a7a test_git: compare state of absent RemoteRef
The next patch will allow setting tracked state to absent remote refs.
2025-10-11 11:59:28 +00:00
Defelo
b38dcbb919 ssh-signing: include key in verification result
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-10-08 13:02:43 +00:00
Yuya Nishihara
c7ffb5d42a view: rename remaining local "tag" functions 2025-09-30 13:51:40 +00:00
Yuya Nishihara
3d4d372b6c view: rename tags() to local_tags(), make it return iterator
This matches the "bookmark" API.
2025-09-30 13:51:40 +00:00
Yuya Nishihara
744631d2bf cleanup: use method version of str::from_utf8()
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
MSRV is now 1.88.

https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8
2025-09-27 09:26:05 +00:00
Yuya Nishihara
120d492d4e git, op_store: migrate and import "refs/tags/*" as @git remote tags
The migration logic is basically the same as 717d0d3d6d "git: on
deserialize/import/export, copy refs/heads/* to remote named git." Now
git::import_refs() processes bookmarks and tags in the same way.
git::export_refs() is unchanged because we don't have any commands that would
move local tags internally.
2025-09-24 09:09:52 +00:00
Yuya Nishihara
a89680d34b op_store: add remote tags storage and basic accessors
Git-tracking tags will be stored there. I don't have a concrete plan for proper
remote tags support, but I think tags fetched/pushed internally can be recorded
as remote tags.
2025-09-24 09:09:52 +00:00
Yuya Nishihara
0dc1beba12 op_store: make local/remote refs helper generic over RemoteView fields 2025-09-24 09:09:52 +00:00
Martin von Zweigbergk
4f456ec824 merge: add a generic Diff<T> type, use in TreeDiffEntry
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
I think this helps readability a bit. I updated `TreeDiffEntry` and a
few related places. I think there are many other places where we could
use the new type.
2025-09-21 16:16:33 +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
bd2807fdbc store: downcast to implementation type by backend_impl()
It should be safer to restrict the type here.
2025-09-20 01:22:47 +00:00