954 Commits

Author SHA1 Message Date
Yuya Nishihara
3711979a8f absorb: show warning if source commit contains file deletion 2025-01-16 01:09:33 +00:00
Bryce Berger
f7431650be templates: add cryptographic_signature display to default formats
Cryptographic signature support in templates was added in
c99c97c6467fee3f3269d2934c10c758e041f834 (#4853), but has to be manually
configured. This adds some defaults to the built-in config.

Instead of having separate `builtin_*_with_sig` aliases, this adds to
the aliases that actually format commits. Since signature verification
is slow, this is disabled by default. To enable it, override
`ui.show-cryptographic-signatures`:

    [ui]
    show-cryptographic-signatures = true
    [template-aliases]
    'format_short_cryptographic_signature(signature)' = ...
    'format_detailed_cryptographic_signature(signature)' = ...

Note that the two formatting functions take
`Option<CryptographicSignature>`, not `CryptographicSignature`. This
allows you to display a custom message if a signature is not found, but
will emit an error if you do not check for signature presence.

    [template-aliases]
    'format_detailed_cryptographic_signature(signature)' = '''
      if(signature,
        "message if present",
        "message if missing",
      )
    '''
2025-01-15 23:29:35 +00:00
Yuya Nishihara
284aee25a9 revset: duplicate Rule::identifier to strict_identifier, replace some usages
The "identifier" rule will be changed to accept unicode characters. It's not
super important to reject non-ASCII string pattern prefixes or alias symbols,
but this is more consistent with templater and fileset. We can relax the rule
later if needed.
2025-01-15 07:24:10 +00:00
Yuya Nishihara
f9906dc403 cli: add "git.push-new-bookmarks" config knob to enable --allow-new by default
This goes against our rule that we shouldn't add config knob that changes the
command behavior, but I don't have any other idea to work around the problem.
Apparently, there are two parties, one who always wants to push new bookmarks,
and the other who mildly prefers to push&track new bookmarks explicitly.
Perhaps, for the former, creation of bookmarks means that the target branches
are marked to be pushed.

The added flag is a simple boolean. "non-tracking-only" behavior #5173 could be
implemented, but I don't want to complicate things. It's a failed attempt to
address the issue without introducing config knob.

Closes #5094
Closes #5173
2025-01-15 07:23:43 +00:00
Yuya Nishihara
d00c02fb07 cli: git: mention git.private-commits in --allow-private help text
Since the set is empty by default, --allow-private is noop unless the private
revset is configured by user. Let's clarify that.
2025-01-15 00:28:20 +00:00
Stephen Jennings
be5eb27f16 fix: Add enabled config for fix tools
Adds an optional `fix.tools.TOOL.enabled` config that disables use of a fix
tool (if omitted, the tool is enabled). This is useful for defining tools in
the user's configuration without enabling them for all repositories:

```toml
# ~/.jjconfig.toml
[fix.tools.rustfmt]
enabled = false
command = ["rustfmt", "--emit", "stdout"]
patterns = ["glob:'**/*.rs'"]
```

Then to enable it in a repository:

```shell
$ jj config set --repo fix.tools.rustfmt.enabled true
```
2025-01-13 17:29:49 +00:00
Jakob Hellermann
8a8d8859ea cli: autocomplete: complete config values in addition to keys
Now `jj --config ui.con<TAB><TAB>` will autocomplete

```
ui.conflict-marker-style=diff
ui.conflict-marker-style=snapshot
ui.conflict-marker-style=git
```

Booleans are completed as `false`, `true`, the remaining types are left
without completions.
2025-01-13 14:43:40 +00:00
Jakob Hellermann
270b54209e cli: autocomplete: complete --config with possible configuration keys
the trailing `=` is especially nice to have because otherwise fish will
complete the suggestion and insert a space before the cursor.
With the `=`, `jj config --config ui.pagin<TAB>never` works.
2025-01-12 17:53:22 +00:00
Benjamin Tan
9aaf98330b cli: git push: allow signing commits on push
This adds the `git.sign-on-push` configuration which can be used to
automatically sign unsigned commits before pushing to a Git remote.
2025-01-12 02:33:32 +00:00
Benjamin Tan
d7f064c311 cli: op log: add --reversed option
Closes #4190.
2025-01-12 01:51:25 +00:00
Benjamin Tan
9b45c90cc5 tests: remove unnecessary format_time_range template alias
This is already set in the test configuration.
2025-01-12 01:51:25 +00:00
Yuya Nishihara
89e0a7021a cli: git: store absolute remote path in config file
The "git" CLI chdir()s to the work tree root, so paths in config file are
usually resolved relative to the workspace root. OTOH, jj doesn't modify the
process environment, so libgit2 resolves remote paths relative to cwd, not to
the workspace root. To mitigate the problem, this patch makes "jj git remote"
sub commands to store resolved path in .git/config. It would be nice if we can
reconfigure in-memory git2 remote object to use absolute paths (or set up
in-memory named remote without writing a config file), but there's no usable
API afaik.

This behavior is different from "git remote add"/"set-url". I don't know the
rationale, but these commands don't resolve relative paths, whereas "git clone"
writes resolved path to .git/config. I think it's more consistent to make all
"jj git" sub commands resolve relative paths.
2025-01-12 01:45:03 +00:00
Jakob Hellermann
f1e91cdab5 cli: complete: fix stderr during autocomplete of revsets
When running `cmd.spawn()` rust will by default inherit
the stderr of the parent, so `jj log test<TAB>`, would
print `There is no jj repo in "."` into the prompt.
2025-01-11 12:34:21 +00:00
Yuya Nishihara
98724278c5 templater: add config(name) function
This could be used in order to switch template outputs conditionally, or to
get the default push remote for example.
2025-01-11 01:40:23 +00:00
Yuya Nishihara
83d237a32c templater: introduce ConfigValue type, port "config list" value to it
I'm going to add config(name) accessor, which returns ConfigValue.
2025-01-11 01:40:23 +00:00
Yuya Nishihara
8e5a18b26e op diff: remove redundant "Change {change_id}" from changed commits graph
This makes the graph compact. Short change ids are usually printed as a part
of commit summary. The --no-graph output is a bit harder to parse, but we can
still discriminate entries by change ids.
2025-01-11 01:23:51 +00:00
Benjamin Tan
9f533aeb78 cli: util: rename mangen to install-man-pages
The `jj util install-man-pages` command will generate man pages for all
`jj` subcommands and install them to the provided destination.

Closes #4157.
2025-01-10 18:54:05 +00:00
Yuya Nishihara
e124404af3 cli: remove handling of deprecated fix.tool-command config
I originally implemented this as a custom config migration rule, but the next
release is v0.26, so we can just drop support for fix.tool-command.
2025-01-10 05:45:16 +00:00
Yuya Nishihara
b97b7384bb config: allow inline table syntax in mutation and conditional scope API
This is a middle ground. An inline table can still be overwritten or deleted
because it's syntactically a value. It would be annoying if "jj config set
colors.<name> '{ .. }'" couldn't be executed more than once because the existing
item was a table.

#5255
2025-01-10 02:56:21 +00:00
Yuya Nishihara
ce6119a024 tests: insert insta::allow_duplicates! { .. } per snapshot
This might be a bug of insta, but new snapshots were associated with wrong
assertion blocks if allow_duplicates! { .. } contained multiple assertions.
2025-01-10 01:00:09 +00:00
Jakob Hellermann
80c4222399 cli: oplog: add builtin_op_log_oneline template
Motivation:
* one-line logs can be more readable and fit more content into the screen
* consistency with `jj log -T builtin_log_oneline`
2025-01-09 15:58:40 +00:00
Yuya Nishihara
720c903b99 git: port s/bookmark/branch/ renames to config migration rules
These two are easy. "fix.tool-command" will be processed by a custom migration
rule of Box<dyn Fn(&mut ConfigLayer) -> ..> type.
2025-01-09 07:23:08 +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
Bryce Berger
b1b2c62c3e diff: add merge-tools.*.diff-expected-exit-codes
Certain tools (`diff`, `delta`) exit with code 1 to indicate there was
a difference. This allows selectively suppressing the "Tool exited with
... status" warning from jj when generating a diff.

example:
```toml
[merge.tools.delta]
diff-expected-exit-codes = [0, 1]
```
2025-01-08 08:03:59 +00:00
Yuya Nishihara
d001291a27 Back out "config: merge and print inline tables as values"
This backs out commit 0de36918e4c020e0e54816f29c47cb57cc9cfbf5. 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
e6c0692655 cli: warn if command matches with aliases inserted by --config* arguments
Closes #5282
2025-01-08 09:40:31 +09: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
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
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
Christian Stoitner
ae91f2265f status: show untracked files 2025-01-05 17:43:59 +01:00
Yuya Nishihara
2cb3ee5260 cli: restore: add --interactive flag
As Martin suggested, this is the reverse operation of "jj diffedit", and
supports fileset arguments.

https://github.com/jj-vcs/jj/issues/3012#issuecomment-1937353458

Closes #3012
2025-01-05 10:14:29 +09:00
Yuya Nishihara
0d022f1202 cli: fix interactive diff selection to not retain unmatched files
This patch doesn't fix DiffEditor::edit() API, which is fundamentally broken
if matcher argument is specified. I'm not sure if the builtin behavior is
correct or not. Suppose we add "jj diffedit FILESETS..", it would probably make
sense to leave unmatched paths unmodified because it is the command to edit the
destination (or right) tree. This is the edit_diff_external() behavior.

Fixes #5252
2025-01-04 22:21:37 +09: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 bfb7613d5d192d3c4dc533afa4f2ff0d6b9016c5).

Co-authored-by: necauqua <him@necauq.ua>
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
5842e58db6 cli: add test that runs basic jj commands with minimal configuration 2025-01-04 17:54:28 +09:00
Austin Seipp
66151f0888 cli: drop support for jj init --{git, git_repo}
These were deprecated early last year in favor of `jj git init`.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
2025-01-03 10:15:01 -06:00
Yuya Nishihara
e306f84765 cli: add "ui.editor" type that captures configuration
The idea is the same as diff_editor()/selector() API. This object will be passed
in to edit_*description() functions in place of (repo_path, settings) pair.

"ui.editor" isn't specific to editing commit descriptions, but it's mainly used
for that purpose. So I put the wrapper type in description_util.rs.
2025-01-03 10:23:58 +09:00
Yuya Nishihara
e344c21a28 cli: use insta snapshot to test editor error messages 2025-01-03 10:23:58 +09:00
JDSeiler
d5b0aa20cb evolog: Implement --reversed flag
Adds some additional helper functions for converting between jj_lib's
GraphEdge and the graphlog's Edge type.
2025-01-02 20:21:59 -05: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
Benjamin Tan
8d560748c7 cli: help: fix typos 2024-12-28 04:08:52 +08:00
Bryce Berger
1d3c3b8ab2 describe: ignore everything below ignore-rest line
This implements "scissor" lines. For example:

    this text is included in the commit message
    JJ: ignore-rest
    this text is not, and is encouraged to be rendered as a diff
    JJ: ignore-rest
    this text is *still not* included in the commit message

When editing multiple commit messages, the `JJ: describe {}` lines
are parsed before the description is cleaned up. That means that the
following will correctly add descriptions to multiple commits:

    JJ: describe aaaaaaaaaaaa
    this text is included in the first commit message
    JJ: ignore-rest
    scissored...
    
    JJ: describe bbbbbbbbbbbb
    this text is included in the first commit message
    JJ: ignore-rest
    scissored...
2024-12-23 16:31:55 -07:00
Scott Taylor
542d09c6a9 merge_tools: add "$marker_length" variable
Git supports passing the conflict marker length to merge drivers using
"%L". It would be useful if we also had a way to pass the marker length
to merge tools, since it would allow Git merge drivers to be used with
`jj resolve` in more cases. Without this variable, any merge tool that
parses or generates conflict markers could fail on files which require
conflict markers longer than 7 characters.

https://git-scm.com/docs/gitattributes#_defining_a_custom_merge_driver
2024-12-23 08:42:10 -06:00
Yuya Nishihara
6374dd0cfe cli: abandon, describe: parse -rREV option properly
I often do "jj log -rREV" to preview the commits to abandon, and it's annoying
that I have to remove -r or insert space to "jj abandon ..".

The implementation is basically the same as b0c7d0a7e262.
2024-12-23 22:58:06 +09:00
Yuya Nishihara
d91e355674 cli: git clone: convert local Git remote path to slash-separated path
Since source.contains(':') can't be used for non-local path detection on
Windows, we now use gix::url for parsing. It might be stricter, but I assume it
would be more reliable.

Closes #4188
2024-12-23 09:40:52 +09:00
Scott Taylor
7bf31c1557 merge_tools: preserve executable bit on resolve 2024-12-22 10:12:22 -06:00
Scott Taylor
afa2f2deca resolve: demo executable bit being lost
Currently, `jj resolve` always sets the file to be non-executable
whenever a conflict is fully resolved. This is confusing, because it can
cause the executable bit to be lost even if every side agrees that the
file is executable.
2024-12-22 10:12:22 -06: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