Commit graph

4385 commits

Author SHA1 Message Date
Yuya Nishihara
98eaadf280 config: add simple migration logic to update deprecated variables
Instead of resolving deprecated variables by callers or config object, this
patch adds a function that rewrites deprecated variables globally (and emits
warnings accordingly.)  It's simpler because StackedConfig doesn't have to deal
with renamed variables internally. OTOH, warnings will be issued no matter if
variables are used or not, which might be a bit noisy.

Maybe we can also add "jj config migrate" command that updates user and repo
configs.
2025-01-09 07:23:08 +00:00
Yuya Nishihara
3fbf1249f9 files: use Merge constructor to interleave conflicting diff parts
Since we build a temporary Vec<_> anyway, we can just rely on the Merge API.
2025-01-09 06:54:09 +00:00
Yuya Nishihara
3d4b5e45e7 merge: inline trivial_merge_inner()
All callers pass &[T] now.
2025-01-09 06:54:09 +00:00
Martin von Zweigbergk
8a3ae86b38 merge: update test values to be simpler and more clearly exhaustive 2025-01-09 00:07:05 +00:00
Martin von Zweigbergk
71494299bb merge: make trivial_merge() take a single slice of interleaved terms
I have come to think of conflicts more and more as one positive
followed by a series of diffs and less as two separate sets of adds
and removes. We've already changed the implmentation of `Merge` to be
a single list of interleaved positive and negative terms. I think it's
simpler to use the same format in `trivial_merge()` too.

To keep the diff simple, I just preserved the test case values and
order as is for now even if that means that some of them are now
unintuitive. I'll clean that up in the next commit.
2025-01-09 00:07:05 +00:00
Scott Taylor
7df0f16fe0 resolve: try to resolve all conflicted files in fileset
If many files are conflicted, it would be nice to be able to resolve all
conflicts at once without having to run `jj resolve` multiple times.
This is especially nice for merge tools which try to automatically
resolve conflicts without user input, but it is also good for regular
merge editors like VS Code.

This change makes the behavior of `jj resolve` more consistent with
other commands which accept filesets since it will use the entire
fileset instead of picking an arbitrary file from the fileset.

Since we don't support passing directories to merge tools yet, the
current implementation just calls the merge tool repeatedly in a loop
until every file is resolved, or until an error occurs. If an error
occurs after successfully resolving at least one file, the transaction
is committed with all of the successful changes before returning the
error. This means the user can just close the editor at any point to
cancel resolution on all remaining files.
2025-01-08 23:52:21 +00:00
Austin Seipp
6083135f19 lib: remove hack to migrate old git remotes
Deletes another vestigial trace of git in the lib crate.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
2025-01-08 22:02:21 +00:00
Austin Seipp
e15429ba91 cli: make git support optional
There are some experiments to try and compile `jj` to WebAssembly, so that we
might be able to do things like interactive web tutorials. One step for that
is making `git` support in `jj-cli` optional, because we can stub it out for
something more appropriate and it's otherwise a lot of porting annoyance for
both gitoxide and libgit2.

(On top of that, it might be a useful build configuration for other experiments
of mine where removing the need for the large libgit2 depchain is useful.)

As part of this, we need to mark `jj-lib` as having `default-features = false`
in the workspace dependency configuration; otherwise, the default behavior
for Cargo is to compile with all its default features, i.e. with git support
enabled, ignoring the `jj-cli` features clauses.

Other than that, it is fairly straightforward junk; it largely just sprinkles
some `#[cfg]` around liberally in order to make things work. It also adjusts the
CI pipeline so this is tested there, too, so we can progressively clean it up.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
2025-01-08 22:02:21 +00:00
Austin Seipp
992066c60c lib: remove use of zstd
`zstd` is only used to write files in the native backend right now. For now,
jettison it, to unbundle some C code that we don't really need.

(Ideally, a future compression library would be pure Rust, but we'll cross that
bridge when we get to it...)

Signed-off-by: Austin Seipp <aseipp@pobox.com>
2025-01-08 22:02:21 +00:00
Yuya Nishihara
d001291a27 Back out "config: merge and print inline tables as values"
This backs out commit 0de36918e4. Documentation,
tests, and comments are updated accordingly. I also add ConfigTableLike type
alias as we decided to abstract table-like items away.

Closes #5255
2025-01-08 05:24:55 +00:00
Yuya Nishihara
49999a7507 local_working_copy: on snapshot, ignore submodule in ignored directories
Fixes #5246
2025-01-08 09:39:59 +09:00
Martin von Zweigbergk
4a7d9891e6 rewrite: back out 9d4a973
I think the test case added in the previous commit shows a clear case
for why commit 9d4a973 was a bad idea.
2025-01-07 09:08:46 -08:00
Martin von Zweigbergk
ada946db62 rewrite: add another test of rebasing with same change on both sides 2025-01-07 09:08:46 -08:00
Scott Taylor
e6a51d6637 git: add dummy conflict to index if necessary
If the parent tree contains conflicts, we want the index to also contain
a conflict to ensure that the use can't accidentally commit conflict
markers using `git commit`. Since we can't represent conflicts with more
than 2 sides in the Git index, we need to add a dummy conflict in this
case. We use ".jj-do-not-resolve-this-conflict" as the dummy conflict to
indicate to the user that they should not attempt to resolve this
conflict using Git.
2025-01-06 19:17:51 -06:00
Scott Taylor
42b390bbc4 git: use merged parent tree for git index
Instead of setting the index to match the tree of HEAD, we now set the
index to the merged parent tree of the working copy commit. This means
that if you edit a merge commit, it will make the Git index look like it
would in the middle of a `git merge` operation (with all of the
successfully-merged files staged in the index).

If there are any 2-sided conflicts in the merged parent tree, then they
will be added to the index as conflicts. Since Git doesn't support
conflicts with more than 2 sides, many-sided conflicts are staged as the
first side of the conflict. The following commit will improve this.
2025-01-06 19:17:51 -06:00
Scott Taylor
9cc8b35251 git: use gix instead of git2 to update index
This will give us more fine-grained control over what files we put in
the index, allowing us to create conflicted index states. We also still
need to use git2 to clean up the merge/rebase state, since gix doesn't
have any function for this currently.
2025-01-06 19:17:51 -06:00
Scott Taylor
8e3ec9c58c git: add tests for index in colocated repo
These tests should still pass after we switch to gix for resetting the
index, so we need to make sure they don't rely on the cached index from
the `git2::Repository` instance.
2025-01-06 19:17:51 -06:00
Scott Taylor
3f72604832 git: make update_git_head accept an expected ref
This change will allow `update_git_head` to be used in `reset_head`.
2025-01-06 19:17:51 -06:00
Yuya Nishihara
b8653989c1 tests: add convenient method to initialize TestWorkspace with test settings
Functions are renamed, and their arguments are reordered to be consistent with
the TestRepo API.
2025-01-06 22:37:33 +09:00
Yuya Nishihara
6c14ccd89d cli: resolve settings for newly initialized/cloned workspace
Fixes #5144
2025-01-06 10:39:48 +09:00
Yuya Nishihara
393f3acb03 workspace: add settings() getter 2025-01-06 10:39:48 +09:00
Christian Stoitner
cb28685901 working_copy: added UntrackedReason::FileNotAutoTracked for files not tracked because of snapshot.auto-track 2025-01-05 17:43:59 +01:00
Anton Bulakh
c99c97c646 sign: Add templater methods to show signature info
Disclaimer: this is the work of @necauqua and @julienvincent (see
#3141). I simply materialized the changes by rebasing them on latest
`main` and making the necessary adjustments to pass CI.

---

I had to fix an issue in `TestSignatureBackend::sign()`.

The following test was failing:
```
---- test_signature_templates::test_signature_templates stdout ----
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Snapshot Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Snapshot: signature_templates
Source: cli/tests/test_signature_templates.rs:28
────────────────────────────────────────────────────────────────────────────────
Expression: stdout
────────────────────────────────────────────────────────────────────────────────
-old snapshot
+new results
────────────┬───────────────────────────────────────────────────────────────────
    0     0 │ @  Commit ID: 05ac066d05701071af20e77506a0f2195194cbc9
    1     1 │ │  Change ID: qpvuntsmwlqtpsluzzsnyyzlmlwvmlnu
    2     2 │ │  Author: Test User <test.user@example.com> (2001-02-03 08:05:07)
    3     3 │ │  Committer: Test User <test.user@example.com> (2001-02-03 08:05:07)
    4       │-│  Signature: Good test signature
          4 │+│  Signature: Bad test signature
    5     5 │ │
    6     6 │ │      (no description set)
    7     7 │ │
    8     8 │ ◆  Commit ID: 0000000000000000000000000000000000000000
────────────┴───────────────────────────────────────────────────────────────────
```

Print debugging revealed that the signature was bad, because of a
missing trailing `\n` in `TestSignatureBackend::sign()`.

```diff
diff --git a/lib/src/test_signing_backend.rs b/lib/src/test_signing_backend.rs
index d47fef1086..0ba249e358 100644
--- a/lib/src/test_signing_backend.rs
+++ b/lib/src/test_signing_backend.rs
@@ -59,6 +59,8 @@
         let key = (!key.is_empty()).then_some(std::str::from_utf8(key).unwrap().to_owned());

         let sig = self.sign(data, key.as_deref())?;
+        dbg!(&std::str::from_utf8(&signature).unwrap());
+        dbg!(&std::str::from_utf8(&sig).unwrap());
         if sig == signature {
             Ok(Verification::new(
                 SigStatus::Good,
```

```
[lib/src/test_signing_backend.rs:62:9] &std::str::from_utf8(&signature).unwrap() = \"--- JJ-TEST-SIGNATURE ---\\nKEY: \\n5300977ff3ecda4555bd86d383b070afac7b7459c07f762af918943975394a8261d244629e430c8554258904f16dd9c18d737f8969f2e7d849246db0d93cc004\\n\"
[lib/src/test_signing_backend.rs:63:9] &std::str::from_utf8(&sig).unwrap() = \"--- JJ-TEST-SIGNATURE ---\\nKEY: \\n5300977ff3ecda4555bd86d383b070afac7b7459c07f762af918943975394a8261d244629e430c8554258904f16dd9c18d737f8969f2e7d849246db0d93cc004\"
```

Thankfully, @yuja pointed out that libgit2 appends a trailing newline
(see bfb7613d5d).

Co-authored-by: necauqua <him@necauq.ua>
Co-authored-by: julienvincent <m@julienvincent.io>
2025-01-04 13:24:08 +01:00
pylbrecht
87b38b3073 sign: provide display in TestSigningBackend
We need to provide a value for the `display` attribute to assert against
in upcoming tests, which verify signature templates.
2025-01-04 13:24:08 +01:00
pylbrecht
638f123459 sign: move TestSigningBackend to lib
We need to make `TestSigningBackend` available for cli tests, as we will
add cli tests for signing related functionality (templates for
displaying commit signatures, `jj sign`) in upcoming commits.

Co-authored-by: julienvincent <m@julienvincent.io>
2025-01-04 13:24:08 +01:00
Yuya Nishihara
fcac7ed39c config: load system host/user name by CLI and insert as env-base layer
Since the default now falls back to "", we can simply override the default by
CLI. We don't have to touch the environment in jj-lib.
2025-01-04 17:54:28 +09:00
Yuya Nishihara
c7dd28a292 settings: fall back to empty op hostname/username if default can't be obtained
It's not super important that operation log has a valid user/host name. Let's
allow invalid system configuration. In jj 0.24.0, invalid hostname was panic,
and invalid username was mapped to "Unknown".

Fixes #5231
2025-01-03 10:20:33 +09:00
Yuya Nishihara
cdbe4dfc67 signing: cap number of cached verification results
I didn't notice Signer had a cache when I made the change db6a58d315 "store:
switch in-memory cache to LRU-based HashMap to cap memory usage."
2025-01-02 15:06:52 +09:00
Waleed Khan
a28edb0d28 docs: fix cargo doc warnings 2024-12-31 17:11:28 -06:00
Waleed Khan
c7b677b86d build: switch back to gix/max-performance-safe feature by default
Using `gix/max-performance` requires `cmake` as a build-time dependency, which could be a significant barrier for contributors (including existing ones, like me, who already work on jj but didn't have `cmake` installed thus far).

This commit switches back to using `gix/max-performance-safe`, which doesn't have the `cmake` dependency, and adds `gix/max-performance` behind the `gix-max-performance` feature for `jj-lib`.

It also adds `gix-max-performance` to the `packaging` feature group, since I'm assuming that packagers will want maximum performance, and are more likely to have `cmake` at hand.

Tested with

```
$ cargo build --workspace
$ cargo build --workspace --features packaging
```

(and the `--features packaging` build failed until I installed `cmake`)
2024-12-31 17:07:52 -06:00
Yuya Nishihara
cff73841ed repo: remove &UserSettings argument from new/rewrite_commit(), use self.settings 2024-12-31 10:51:57 +09:00
Yuya Nishihara
14b52205fb repo: remove &UserSettings argument from start_transaction(), use self.settings 2024-12-31 10:51:57 +09:00
Yuya Nishihara
57806ee8c2 test_commit_builder: reload repo per settings
I'm going to remove the settings argument from start_transaction(),
new_commit(), and rewrite_commit(), and these functions will use the settings
passed in to the constructor.
2024-12-31 10:51:57 +09:00
Yuya Nishihara
475ac4e86a repo: keep copy of UserSettings, remove RepoSettings
The idea is that ReadonlyRepo/MutableRepo hold UserSettings to accomplish
their operations (such as transaction commit.) Later patches will remove
the "settings" argument from a couple of repo methods, which will greatly
reduce the amount of settings refs we had to pass around.

The current UserSettings is set up for the repo, so we wouldn't need a separate
RepoSettings type.
2024-12-31 10:51:57 +09:00
Yuya Nishihara
feb032ee34 settings: make UserSettings cheap to clone
I think the issue #5144 can be fixed cleanly if UserSettings object is
loaded/resolved per repo/workspace, not per CommandHelper.

This change makes it clear that UserSettings is supposed to be shared
immutably.
2024-12-31 10:51:57 +09:00
Yuya Nishihara
43ac4faac4 config: preserve key formatting on set_value()
I just noticed toml_edit::Table has a format-preserving insert() API. I think
it's better to retain the user-specified quoting style.
2024-12-29 09:57:04 +09:00
Yuya Nishihara
10783f9e70 config: don't leave empty tables visible by set_value()
It's unlikely that user would want to define all intermediate tables by
"jj config set foo.bar.baz ..".
2024-12-29 09:57:04 +09:00
Yuya Nishihara
4af39e2038 cli: config list: mark values overridden by table or parent value
This fixes the output of "jj config list --include-overridden --include-defaults
ui.pager" and ".. ui.pager.command". The default ui.pager.* should be marked as
overridden by ui.pager if set in user configuration.
2024-12-28 10:28:43 +09:00
Yuya Nishihara
e5361c6cc0 fsmonitor: move default settings to config/misc.toml 2024-12-25 10:44:37 +09:00
Yuya Nishihara
9b60a9df90 signing: move default backend settings to config/misc.toml 2024-12-25 10:44:37 +09:00
Yuya Nishihara
e4a350fcaa config: extract jj-lib's default values to embedded TOML file
It's nice that "jj config list --include-defaults" can show these default
values.

I just copied the jj-cli directory structure, but it's unlikely we'll add more
config/*.toml files.
2024-12-25 10:44:37 +09:00
Yuya Nishihara
5bd669e892 settings: propagate configuration error of commit and operation parameters
Note that infallible version of whoami::username() would return "Unknown" on
error. I just made it error out, but it's also an option to fall back to an
empty string.
2024-12-23 22:57:57 +09:00
Yuya Nishihara
4a69d0178c settings: cache commit and operation parameters by UserSettings
This helps propagate configuration error. RevsetParseContext is also updated
because it was easier to pass &str in to it.
2024-12-23 22:57:57 +09:00
Yuya Nishihara
6f00c565b2 graph: inline ReverseGraphIterator to callers 2024-12-23 09:28:03 +09:00
Yuya Nishihara
ec853027be graph: make reverse_graph() return nodes in "reversed" order 2024-12-23 09:28:03 +09:00
Yuya Nishihara
d6b84da382 graph: extract function that reverses graph edges
ReverseGraphIterator will be inlined. It doesn't make sense the iterator yields
Item = Result<..> whereas all possible errors are confined by constructor.
2024-12-23 09:28:03 +09:00
Yuya Nishihara
78b5766993 repo, workspace: use dunce::canonicalize() to normalize paths
These paths may be printed, compared with user inputs, or passed to external
programs. It's probably better to avoid unusual "\\?\C:\" paths on Windows.

Fixes #5143
2024-12-22 09:45:37 +09:00
Scott Taylor
6baa43624c local_working_copy: store materialized conflict marker length
Storing the conflict marker length in the working copy makes conflict
parsing more consistent, and it allows us to parse valid conflict hunks
even if the user left some invalid conflict markers in the file while
resolving the conflicts.
2024-12-21 11:36:30 -06:00
Scott Taylor
b11ce6bd28 conflicts: escape conflict markers by making them longer
If a file contains lines which look like conflict markers, then we need
to make the real conflict markers longer so that the materialized
conflicts can be parsed unambiguously.

When parsing the conflict, we require that the conflict markers are at
least as long as the materialized conflict markers based on the current
tree. This can lead to some unintuitive edge cases which will be solved
in the next commit.

For instance, if we have a file explaining the differences between
Jujutsu's conflict markers and Git's conflict markers, it could produce
a conflict with long markers like this:

```
<<<<<<<<<<< Conflict 1 of 1
%%%%%%%%%%% Changes from base to side #1
 Jujutsu uses different conflict markers than Git, which just shows the
-sides of a conflict without a diff.
+sides of a conflict without a diff:
+
+<<<<<<<
+left
+|||||||
+base
+=======
+right
+>>>>>>>
+++++++++++ Contents of side #2
Jujutsu uses different conflict markers than Git:

<<<<<<<
%%%%%%%
-base
+left
+++++++
right
>>>>>>>
>>>>>>>>>>> Conflict 1 of 1 ends
```

We should support these options for "git" conflict marker style as well,
since Git actually does support producing longer conflict markers in
some cases through .gitattributes:

https://git-scm.com/docs/gitattributes#_conflict_marker_size

We may also want to support passing the conflict marker length to merge
tools as well in the future, since Git supports a "%L" parameter to pass
the conflict marker length to merge drivers:

https://git-scm.com/docs/gitattributes#_defining_a_custom_merge_driver
2024-12-21 11:36:30 -06:00
Scott Taylor
369e8ea057 conflicts: refactor conflict marker writing and parsing
These changes make the code a bit more readable, and they will make it
easier to have conflict markers of different lengths in the next commit.
2024-12-21 11:36:30 -06:00