87 Commits

Author SHA1 Message Date
Martin von Zweigbergk
6ef9b28556 op_store: record workspace where operation was run
There are two reasons for this:

 * It helps understanding why divergence happened to see which
   workspace an operation was run from. For example, perhaps an agent
   is running in another workspace and it's not obvious from the
   operation log which commands it ran without seeing the workspace
   name.

 * We may want to check that e.g. `jj undo` is run from the same
   workspace as the operation it's undoing. We may want to print a
   warning otherwise, or maybe we want to skip over operations create
   from other workspaces. I'm not sure what's best but having the
   workspace recorded at least enables such features.
2026-03-24 05:27:00 +00:00
Gaëtan Lehmann
acee40cd5f tests: Replace Result.unwrap with ? operator in test functions
Mostly done with OpenCode and Claude Sonnet 4.6 with the following prompt,
and reviewed manually:

Replace the Result.unwrap with the ? operator in test functions.

While doing that, make sure to:

* Add TestResult as return type in the test functions where you replace
  unwrap by the ? operator, and Ok(()) at the end.
* Do the replacement only in method with the `#[test]` decorator.
* Don't replace unwraps in closures.
* Don't replace Option.unwrap.
* Be careful to not change the insta snapshot references.
* Run the tests each time you're done with a file.
* Keep the unwraps that you can't replace with the ? operator.

Note that:

* You can identify all the Result.unwrap locations with this command:
  cargo clippy --tests --message-format=short -- -W clippy::unwrap_used 2>&1 | grep / | grep Result | grep <filename>
* Begin with the file with the most Result.unwrap in them as shown by
  this command:
  cargo clippy --tests --message-format=short -- -W clippy::unwrap_used 2>&1 | grep Result | cut -d: -f1 | sort | uniq -c | sort -nr
* Some non test files have inline tests.

Before this PR:

❯ cargo clippy --tests --message-format=short -- -W clippy::unwrap_used 2>&1 | grep Result | wc -l
3973

After this PR:

❯ cargo clippy --tests --message-format=short -- -W clippy::unwrap_used 2>&1 | grep Result | wc -l
1064
2026-03-23 19:30:08 +00:00
Martin von Zweigbergk
4bc1b9000a split: warn instead of failing on empty commit with path argument
If the user does something like `jj split @` and the working copy is
not empty, they will get warnings like this:

```
Warning: No matching entries for paths: @
Warning: No changes have been selected, so the new revision will be empty
```

If they run the same command when the working copy is empty, they will
instead get this:

```
Error: Refusing to split empty commit e518dba7418a1b20a545c12ecb16cc870756efa3.
Hint: Use `jj new` if you want to create another empty commit.
```

That's probably less helpful because it's not clear that the `@`
argument was interpreted as a path.

The rationale for the error (in 07559f24ec) is that it's confusing
that an empty diff editor pops up if you accidentally try to split an
empty commit. This patch changes it so we print a warning when the
diff is empty instead of starting the diff editor.
2026-02-21 21:45:34 +00:00
Ilya Grigoriev
3a9e56d06b tests: run cargo insta test --force-update-snapshots
Note that you might get different result if you use cargo-insta <1.63.3
2026-02-17 17:43:54 +00:00
Scott Taylor
c1ecf8a00e git_backend: use first tree as base tree for conflicts
Currently, checking out a commit with conflicts in a colocated workspace
causes many editors to show all existing files as added since they
aren't present in the Git HEAD commit. Using the tree of the first side
of the commit as a base tree and then adding the '.jjconflict-*' trees
on top of it would cause any files identical to the first tree to show
as unchanged, matching Git's conflict behavior.

One potential downside to this change is that it becomes harder for a
user to notice if they incorrectly check out a conflicted commit using
`git switch`, since previously all of their files would've disappeared
so it would be more difficult to ignore. However, I think this could be
solved a different way, such as by adding a warning when snapshotting if
'.jjconflict' files are detected. Keeping the files from the first
tree also has the benefit that '.gitignore' files will still be present,
meaning that when a user does `jj abandon` to recover, it won't delete
their ignored files.

Using 'JJ-CONFLICT-README' as the name for the readme file instead of
'README' makes it more clear that this file is related to the
'.jjconflict-*' trees, since now the repo's actual README file might be
present as well in the tree.
2026-02-12 02:57:05 +00:00
Yuya Nishihara
cb85dba2cb cli: split: ensure trailer is added when message has to be edited
Fixes #8761
2026-02-08 12:08:00 +00:00
Scott Taylor
51020ed6e7 split: add conflict labels
Example of conflict resulting from split:

```
<<<<<<< conflict 1 of 1
%%%%%%% diff from: selected changes for split (from rlvkpnrz 35382813)
\\\\\\\        to: split revision (rlvkpnrz 35382813)
 line 2.1
+line 2.2
+++++++ qpvuntsm ee8e9376 (parents of split revision)
line 2
>>>>>>> conflict 1 of 1 ends
```
2026-01-01 19:41:29 +00:00
Scott Taylor
33ad38bfed templates: add "divergent" label to log for divergent changes
It would be good to include the word "divergent" in the log when a
change is divergent, since users are often unsure what's happening when
they see a divergent change, and giving them a term to search for would
be helpful. However, I don't think it looks good to put this label next
to the change ID itself if both are the same color, since it ends up
being hard to distinguish from the change offset at a glance. Also,
putting the label next to the change ID also messes up the alignment of
fields in the log. Therefore, I think it looks better to put the
"divergent" label at the end of the line.

Since divergence and hidden commits are similar, it makes sense for both
labels to be in the same place, so I also moved the hidden label to the
end for consistency.

One downside is that the labels are less obviously connected with the
change ID itself due to them being farther apart. I think this could be
fine, since they are still visually connected by being the same color.
2025-12-20 16:55:51 +00:00
Scott Taylor
0dffb6f108 templates: show change offsets for divergent and hidden commits
For now, I just replaced `??` with the change offset for divergent
commits. We can add an explicit "divergent" label later.
2025-12-16 02:02:31 +00:00
Yuya Nishihara
97375fa041 revset: enable glob string matching by default
Follows up c93682f2 "revset: parameterize default string pattern kind, add
config knob".
2025-12-15 04:27:32 +00:00
Yuya Nishihara
c6cc177103 config: remove outdated migration rules 2025-12-11 00:49:58 +00:00
Theo Buehler
cfb6509e38 tests: update cargo insta snapshots
Running "cargo insta test --workspace", results in numerous warnings:

Snapshot test passes but the existing value is in a legacy format.
Please run `cargo insta test --force-update-snapshots` to update to
a newer format.

This commit is the result of running the suggested command.
2025-12-09 18:59:34 +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
8091682c0b revset: allow unquoted * in identifier (or pattern expression)
I'm going to fix parsing of CLI string patterns to use revset parser, and it
would be annoying if inner quotes were required in addition to shell quotes:

  $ jj bookmark list 'glob:"push-*"'

There's also a plan to enable glob matching globally. This will mean that we'll
have to use either `subject(*foo*)` or `subject(substring:foo)` for substring
search.

https://github.com/jj-vcs/jj/issues/6971#issuecomment-3067038313
2025-11-15 04:11:57 +00:00
Tejas Sanap
0c6529d1cc cli: jj split warns when fileset doesn't exist 2025-11-10 22:56:32 +00:00
Luke Randall
b433a54ecb cli: split: add --editor flag 2025-11-10 16:13:07 +00:00
Martin von Zweigbergk
32aee9dbdf cli: deprecate --destination/-d in favor of --onto/-o
As we have discussed many times on Discord and GitHub, `--destination`
is not a great name because `--insert-before` and `--insert-after` are
also destinations. The most popular alternative seems to be
`--onto`. We already use that term in descriptions in several places,
such as in the help text for `rebase -d` where we say "The revision(s)
to rebase onto". This patch therefore renames the `--destination` flag
to `--onto`.

The short name naturally becomes `-o`. That is perhaps a little
unfortunate because it's a common short name for `--output <file>`
arguments, but we don't use that anywhere so it seems fine.

Perhaps we should also rename `--source` (used by `rebase` and `fix`)
to something else. Perhaps the most obvious name is `--descendants`,
but the short form would be `-d`, which is of course already taken by
`--destination` in the case of `rebase`. Either way, I'm leaving that
rename for later. It would be good to do it before next release if we
are going to do it, though.

Closes #7941
2025-11-08 14:56:37 +00:00
Yuya Nishihara
b384097caa tests: do not use "jj undo" to run multiple tests with the same setup
Since "undo" is now a high-level command, we shouldn't rely on "undo" to roll
back to a certain state.
2025-08-26 00:27:29 +00:00
Yuya Nishihara
6e63c5d9aa templates: remove operation timestamp from default evolog template
The operation timestamp is often very close to the committer timestamp, so I
don't think it's useful in evolog. I also removed "root()" as it wouldn't be
useful either, and the root operation should have no evolved commits.
2025-08-25 05:52:37 +00:00
Hegui Dai
569ec5ddfe config: show IDs in draft description 2025-08-21 23:52:26 +00:00
Martin von Zweigbergk
98d884827e cli: for deprecated configs, say at which source level they were found
I had a report from a user at Google who was confused about a config
deprecation message because they had forgotten that they set a
repo-level config. This patch includes the source level in the warning
message. Hopefully that's sufficient. We could of course print the
path too, but that would make the message much longer so we would have
to split it up on two lines and I'm not sure it's worth it.
2025-05-28 20:01:51 +00:00
Yuya Nishihara
6dfc9de9b4 cli: evolog: show associated operations alongside commits
The output cannot be templated as of now. Maybe we can add a template type for
Commit + Operation?

Closes #963
2025-05-27 13:28:09 +00:00
Gaëtan Lehmann
0b0d313583 split: use "selected/remaining changes" instead of "first/second commits"
With the new -A/-B/-d flags, the new commit may be created anywhere in
the tree, making the denomination first/second commit inaccurate.
2025-05-16 07:55:12 +00:00
Yuya Nishihara
2d79c6431d templater: introduce newtype to format ref/remote name in revset syntax
This is the last part of the series 02722eae54 "view: port bookmark/tag name
types to RefName/RemoteName." Templater doesn't use these name types internally
because we wouldn't gain much type safety in template language.

The return type of .remote() is changed to Option<RefSymbol>. An empty symbol is
rendered with quotes, so it would be weird if local_bookmark.remote() returned
an empty RefSymbol.
2025-05-13 23:54:47 +00:00
Gaëtan Lehmann
193d9452b0 split: implement -A/-B/-d flags
the feature reused as much as possible of the `jj rebase` code, with
minimum modifications, in order to avoid reimplementing or complexifying
the rebase code.
It leads to some cases where some commits may be rewritten twice.

For example:

    ❯ jj -s
    @  ylrkuwto (empty) (no description set)
    ○  qsorlqym file4
    │  A file4
    ○  mmkvzzpw file3
    │  A file3
    ○  uttlrpzl file1&2
    │  A file1
    │  A file2
    ◆  zzzzzzzz root()

    ❯ jj split -r u -A m -m file1 file1
    Rebased 3 descendant commits
    First part: ulpvupsv aaf064bc file1
    Second part: uttlrpzl 0d4358c2 file1&2
    Working copy  (@) now at: ylrkuwto 60d905c5 (empty) (no description set)
    Parent commit (@-)      : qsorlqym 8cfbe2d8 file4

    ❯ jj -s
    @  ylrkuwto (empty) (no description set)
    ○  qsorlqym file4
    │  A file4
    ○  ulpvupsv file1
    │  A file1
    ○  mmkvzzpw file3
    │  A file3
    ○  uttlrpzl file1&2
    │  A file2
    ◆  zzzzzzzz root()

There is an intermediate state created as

    @  ylrkuwto (empty) (no description set)
    ○  qsorlqym file4
    │  A file4
    ○  mmkvzzpw file3
    │  A file3
    ○  uttlrpzl file1&2
    │  A file2
    ○  ulpvupsv file1
    │  A file1
    ◆  zzzzzzzz root()

where the commits in `uttlrpzl::` have been rewritten, then `ulpvupsv`
is moved, effectively rewriting the commits in `ulpvupsv::`.

The number of user visible rewritten commits is accurately reported.

`jj split --parallel` is still done as a special case: implementing
it with the rebase code would put the first commits on the right
branch.
2025-05-13 17:26:00 +00:00
Martin von Zweigbergk
acd824269f git: write change-id header by default
We haven't had any reports of problems from people who opted in. Since
it's early in the release cycle now, let's now test it on everyone who
builds from head, so we get almost a month of testing from those
people before it's enabled by default in a released version.

This impacts lots of test cases because the change-id header is added
to the Git commit. Most are uninteresting. `test_git_fetch` now sees
some divergent changes where it used to see only divergent bookmarks,
which makes sense.
2025-05-08 23:05:38 +00:00
Gaëtan Lehmann
b31c4158cc split: add the --message option
to set the message on the first commit, where the selected
changes are going. The commit with the remaining changes
keeps the original description.
With this option it becomes possible to use split in a fully
non-interactive way, in combination with the filset feature.
It also makes jj split more consistent with other commands
like squash, commit or new.
2025-05-07 21:35:55 +00:00
Yuya Nishihara
af9c608ca5 config: migrate ui.default-description to template alias
Since we now have the template alias, it's easy to migrate the config value
programatically. However, there are a couple of minor behavior changes:

 a. default description won't be used if user customized the
    draft_commit_description template.
 b. default description won't be inserted if trailer is added

For (a), I assumed user would inline the default description in the draft
template if they customized the template. (b) should be okay because the
trailers template is a new feature.
2025-04-21 14:39:47 +00:00
Gaëtan Lehmann
fae66ace9b split: add trailer support 2025-04-18 16:48:01 +00:00
Winter
af60f3d674 cli: deprecate ui.default-description
Closes https://github.com/jj-vcs/jj/issues/6298.
2025-04-17 02:03:48 +00:00
Yuya Nishihara
87a35d5bb2 tests: port test_split_command.rs to TestWorkDir API 2025-04-03 01:43:02 +00:00
Yuya Nishihara
f2ca6b7740 tests: set up fake editor early in test_{split,squash}_command.rs
This helps avoid borrowing issue.
2025-04-03 01:43:02 +00:00
Yuya Nishihara
4bcebe678c cli: pad empty description intro/instruction lines with "JJ:"
Since 7618b52b "cli: consider 'JJ:' lines as comments also when not followed by
space", lines starting with "JJ:" (without space) are also ignored. We can
simply add "JJ:" prefix to empty intro/instruction lines.

Closes #5484
2025-04-01 02:02:02 +00:00
Yuya Nishihara
fd05b6f4cb cli: make description template insert blank line if old description was empty
This helps detect whether the last line is "JJ:" instruction or not. It seems
also nice that I don't have to insert newline to reflow the edited paragraph.
2025-04-01 02:02:02 +00:00
Robin Stocker
0456701e18 cli: Print @ and @- in status and print_updated_working_copy_stats
This helps newcomers learn/remember what @ and @- stand for.
2025-03-31 11:57:04 +00:00
Evan Mesterhazy
83ce245995 cli split: Check the evolog in two tests
This is to ensure two things:

1. That the evolog isn't missing the history from the target commit.
2. That the evolog doesn't include extra "temporary" commits due to
   the way `jj split` is implemented.

The impetus for this is the discussion in https://github.com/jj-vcs/jj/pull/5926.
The changes added here detect the extra temporary commit added to the evolog
when `split --parallel` is run using the implementation in #5926.
2025-03-25 14:21:44 +00:00
Evan Mesterhazy
6ba5a76f51 cli split: Rename "siblings" test to "parallel"
The name of the flag was changed from --siblings to --parallel a while back,
but the tests weren't renamed.

#cleanup
2025-03-24 14:42:40 +00:00
Evan Mesterhazy
bb78c06d76 cli split: Add a simple split with descendants test
We have this test for split --parallel, but we don't actually have a
non-parallel split test where the target commit has descendants.
2025-03-24 14:42:06 +00:00
Evan Mesterhazy
b627924828 cli split: Explain how the diff script works in test_split_interactive_with_paths
It wasn't immediately obvious to me what was happening here, but once I
understood it it seemed pretty simple. Perhaps it's worth a comment to explain
it to the next reader.
2025-03-24 13:58:21 +00:00
Ilya Grigoriev
5eae2d92a0 tests: run insta --force-update-snapshots
This is a replacement for #5558.

Thanks to @yuja 's https://github.com/mitsuhiko/insta/pull/722, this is
now easy to generate.
2025-03-06 21:35:08 +00:00
Evan Mesterhazy
2af5b60d32 cli split: Disable the new bookmark behavior for jj split
The consensus about this change, if one ever existed, seems to have dissolved
into two cohorts, one which is happy with the change, and one which thinks we
should move both the bookmark and change id to the child commit instead of
leaving them on the parent.

We may decide to add flags to allow users to choose between the two behaviors,
but there are also other concerns such as where @ should go (parent or child).
Until we agree on a path forward it seems reasonable to delay the breaking
change by disabling it via the config option we added. I don't think it's
necessary to fully revert the code and new tests since we aren't announcing the
option.


#3419
2025-02-28 23:23:06 +00:00
Yuya Nishihara
7fa8420908 tests: resolve directory path to run_jj_in() relative to env_root
Suppose we'll add test_env.init_workspace(path) or something, this will probably
make sense.
2025-02-25 15:40:14 +00:00
Yuya Nishihara
ad6985fd9c tests: migrate unusual patterns of jj_cmd_ok() to run_jj_in()
These callers are manually ported to run_jj_in().
2025-02-24 15:39:11 +00:00
Yuya Nishihara
804d175fd9 tests: migrate non-snapshot users of jj_cmd_ok() to run_jj_in().success()
These callers were mostly substituted mechanically.
2025-02-24 15:39:11 +00:00
Yuya Nishihara
3193513049 tests: migrate snapshot users of jj_cmd_ok() to run_jj_in()
These callers were mostly substituted mechanically, then fixed up formatting.
2025-02-24 15:39:11 +00:00
Yuya Nishihara
255532b6b8 tests: reorder comments and snapshots, split insta::allow_duplicates! { .. }
This helps replace jj_cmd_ok() by pattern matching.
2025-02-24 15:39:11 +00:00
Yuya Nishihara
cdcc777730 tests: migrate snapshot users of jj_cmd_success() to run_jj_in()
These callers were mostly substituted mechanically, then fixed up minor
formatting and name errors.
2025-02-23 13:34:17 +00:00
Yuya Nishihara
d19e58f591 tests: migrate callers of jj_cmd_failure() to run_jj_in() 2025-02-23 03:06:59 +00:00
Yuya Nishihara
f1cd3a4e53 tests: migrate some jj_cmd_success() output wrappers to run_jj_in() 2025-02-22 01:23:04 +00:00
Yuya Nishihara
b1eca3710c cli: parse bookmark name to be created/updated as revset symbol
This should help prevent misuse of "jj bookmark set" with e.g. remote bookmark
name. A remote-looking bookmark can be created by quoting the name if needed.

This patch doesn't change the parsing of name patterns. For patterns, I think
it's better to add support for compound expressions (e.g. `glob:foo* & ~bar`)
rather than adding revset::parse_string_pattern(text) -> StringPattern.

Closes #5705
2025-02-20 08:05:20 +00:00