Commit graph

3570 commits

Author SHA1 Message Date
Bryce Berger
cbb743cfb5 config: add --when.command to scope resolution
Closes #5217

Motivating use case:

    [[--scope]]
    --when.command = ["log"]
    [--scope.ui]
    pager = "less"

This adds a new (optional) field to `--when` config conditions, to
inspect the current command.

`--when.commands` is a list of space-separated values that matches a
space-separated command. To be specific:

    --when.command = ["file"]        # matches `jj file show`, `jj file list`, etc
    --when.command = ["file show"]   # matches `jj file show`, but *NOT* `jj file list`
    --when.command = ["file", "log"] # matches `jj file` *OR* `jj log` (or subcommand of either)

When both `--when.commands` and `--when.repositories` are set, the
intersection is used.
2025-01-24 05:30:07 +00:00
bsdinis
35440ce1bd git: spawn a separate git process for network operations
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
Reasoning:

`jj` fails to push/fetch over ssh depending on the system.
Issue #4979 lists over 20 related issues on this and proposes spawning
a `git` subprocess for tasks related to the network (in fact, just push/fetch
are enough).

This PR implements this.

Implementation Details:

This PR implements shelling out to `git` via `std::process::Command`.
There are 2 sharp edges with the patch:
 - it relies on having to parse out git errors to match the error codes
   (and parsing git2's errors in one particular instance to match the
   error behaviour). This seems mostly unavoidable

 - to ensure matching behaviour with git2, the tests are maintained across the
   two implementations. This is done using test_case, as with the rest
   of the codebase

Testing:

Run the rust tests:
```
$ cargo test
```

Build:
```
$ cargo build
```

Clone a private repo:
```
$ path/to/jj git clone --config='git.subprocess=true' <REPO_SSH_URL>
```

Create new commit and push
```
$ echo "TEST" > this_is_a_test_file.txt
$ path/to/jj describe -m 'test commit'
$ path/to/jj git push --config='git.subprocess=true' -b <branch>
```


Issues Closed

With a grain of salt, but most of these problems should be fixed (or at least checked if they are fixed). They are the ones listed in #4979 .

SSH:
- https://github.com/jj-vcs/jj/issues/63
- https://github.com/jj-vcs/jj/issues/440
- https://github.com/jj-vcs/jj/issues/1455
- https://github.com/jj-vcs/jj/issues/1507
- https://github.com/jj-vcs/jj/issues/2931
- https://github.com/jj-vcs/jj/issues/2958
- https://github.com/jj-vcs/jj/issues/3322
- https://github.com/jj-vcs/jj/issues/4101
- https://github.com/jj-vcs/jj/issues/4333
- https://github.com/jj-vcs/jj/issues/4386
- https://github.com/jj-vcs/jj/issues/4488
- https://github.com/jj-vcs/jj/issues/4591
- https://github.com/jj-vcs/jj/issues/4802
- https://github.com/jj-vcs/jj/issues/4870
- https://github.com/jj-vcs/jj/issues/4937
- https://github.com/jj-vcs/jj/issues/4978
- https://github.com/jj-vcs/jj/issues/5120
- https://github.com/jj-vcs/jj/issues/5166

Clone/fetch/push/pull:
- https://github.com/jj-vcs/jj/issues/360
- https://github.com/jj-vcs/jj/issues/1278
- https://github.com/jj-vcs/jj/issues/1957
- https://github.com/jj-vcs/jj/issues/2295
- https://github.com/jj-vcs/jj/issues/3851
- https://github.com/jj-vcs/jj/issues/4177
- https://github.com/jj-vcs/jj/issues/4682
- https://github.com/jj-vcs/jj/issues/4719
- https://github.com/jj-vcs/jj/issues/4889
- https://github.com/jj-vcs/jj/discussions/5147
- https://github.com/jj-vcs/jj/issues/5238

Notable Holdouts:
 - Interactive HTTP authentication (https://github.com/jj-vcs/jj/issues/401, https://github.com/jj-vcs/jj/issues/469)
 - libssh2-sys dependency on windows problem (can only be removed if/when we get rid of libgit2): https://github.com/jj-vcs/jj/issues/3984
2025-01-23 16:50:53 +00:00
bsdinis
c773c0296f git: test git fetch with more than two remotes and branches
In some cases, there are non trivial codepaths for fetching multiple
branches explicitly. In particular, it might be the case that fetching
works for n = 2 but not n = 3.

This commit changes a cli test to have 3 remotes and 3 branches, and a
lib test with 3 branches, only one of them succeds.
2025-01-23 16:50:53 +00:00
bsdinis
717ae02f62 lib: add type support for refspecs
Fully qualified git refs (e.g., `+refs/head/main:refs/remotes/origin/main`)
are commonly used throughout the git glue code.

It is laborious and error prone to keep parsing refspecs when we need
only a segment of it.

This commits adds a type, `RefSpec`, which does exactly that
2025-01-23 16:50:53 +00:00
Yuya Nishihara
721aecb4cc config: add public ConfigLayer::ensure_table() function
It's not uncommon to insert new table at a certain path. This could be modelled
as set_table(name, new_table), but the caller might want to merge items with
the existing table if any. This function can be used for both cases.
2025-01-22 01:01:04 +00:00
Yuya Nishihara
d9e0fb7974 config: add migration type that runs user-specified function
This was needed in order to migrate fix.tool-command to [fix.tools] table. We
don't have other use cases right now, but there will be something in future.
2025-01-22 01:01:04 +00:00
Yuya Nishihara
ffaaf89f05 config: add migration type that renames and updates value
This will be used in order to migrate boolean value to enum, for example.
2025-01-22 01:01:04 +00:00
Yuya Nishihara
9d77ad5594 config: add separate type for migration error, attach source path
Migration can fail because of unexpected value type, etc.
2025-01-22 01:01:04 +00:00
Yuya Nishihara
a6f20cf42f graph: make reverse_graph() accept separate node id type
Although extra clone/IO wouldn't matter in practice, we can simplify callers
by constructing the edges list to be passed to the graph renderer.
2025-01-22 00:44:42 +00:00
Yuya Nishihara
b70d0c50e1 graph: remove redundant clone from reverse_graph()
All input nodes should be unique.
2025-01-22 00:44:42 +00:00
Yuya Nishihara
c50a70906b rewrite: add option to delete abandoned bookmarks
I'll make "jj abandon" delete bookmarks by default. This could be handled by
cmd_abandon(), but we'll need a repo API if we also want to change the behavior
of "jj rebase --skip-emptied".
2025-01-21 02:37:07 +00:00
Yuya Nishihara
ace041ec96 rewrite: add a few more bookmarks to abandoning test, remove redundant assertion 2025-01-21 02:37:07 +00:00
Yuya Nishihara
a3636d8a83 revset: add subject() predicate that matches first line of descriptions
It's generally useful, and we can get by without introducing weird special case
about newline terminator.

Closes #5227
2025-01-21 02:13:04 +00:00
Yuya Nishihara
5577ffd28d revset: split author()/committer() into _name()/email() predicates
It seemed weird that we don't have primitive functions to query either name or
email field. This also fixes mine() to not match against name.
2025-01-21 01:10:00 +00:00
Yuya Nishihara
206acadd49 revset: remove stale comment about regex pattern 2025-01-21 01:10:00 +00:00
Ilya Grigoriev
027589d199 cleanup: remove WatchmanConfig Default impl
Some checks failed
binaries / Build binary artifacts (push) Has been cancelled
website / prerelease-docs-build-deploy (ubuntu-24.04) (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
This one was actually used, but only in a debug command.
2025-01-18 07:49:43 +00:00
Ilya Grigoriev
3404085ec4 cleanup: remove Conflict default impl
The "default" conflict is not a valid conflict, as it
does not have one more add than removes.
2025-01-18 07:49:43 +00:00
Ilya Grigoriev
5daa138cd7 cleanup: remove a bunch of unused Default impls
I noticed that some config structures do not use their "Default" implementation, and have their default specified in a TOML file. I think specifying defaults in TOML is great, and it'd be good to delete those Default implementations, so that it does not diverge from the default in the TOML file.
2025-01-18 07:49:43 +00:00
Yuya Nishihara
83d40d2c42 repo: move rebase_descendants_with_options_return_map() to tests
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-01-18 01:21:28 +00:00
Yuya Nishihara
15f4ac5f12 repo: add rebase_descendants_*() that takes callback instead of returning map
There's only one non-test caller who doesn't need a complete map of rebased
commits.

FWIW, I tried to rewrite squash_commits() based on transform_descendants() API,
but it wasn't easy because of A-B+A=A rule. The merge order matters here.
2025-01-18 01:21:28 +00:00
Yuya Nishihara
e3efb0d614 rewrite: pass RebaseOptions by reference
Since we've removed DescendantRebaser, it no longer makes sense to pass options
by value. This patch also replaces Default::default() for clarity.
2025-01-18 01:21:28 +00:00
Yuya Nishihara
5d1f3d006d repo: pass &Commit to record_abandoned_commit() to simplify error handling
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-01-17 00:28:25 +00:00
Yuya Nishihara
8833a7adc7 repo: propagate error from record_rewrites() 2025-01-17 00:28:25 +00:00
Yuya Nishihara
cb981c7bf1 git: propagate error from abandon_unreachable_commits() 2025-01-17 00:28:25 +00:00
Yuya Nishihara
646bdabe62 absorb: print status if source commit still contains diffs
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
Closes #5362
2025-01-16 01:09:33 +00:00
Yuya Nishihara
e910ac4040 absorb: wrap absorb_hunks() result in struct
This patch also renames rewritten_commits as I'm going to add rewritten_source
field.
2025-01-16 01:09:33 +00:00
Yuya Nishihara
3711979a8f absorb: show warning if source commit contains file deletion 2025-01-16 01:09:33 +00:00
Yuya Nishihara
4dd554aa69 revset: parse unicode XID_CONTINUE characters as symbol
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
Tag and bookmark names are usually ASCII, but they occasionally include Latin
or Han characters.

This doesn't fix the serialization problem, but should mitigate #5359.
2025-01-15 07:24:10 +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
0fbf2913ac revset: extract identifier/at_op parsing tests to separate functions
I'm going to add some unicode characters there, and the current test function
is pretty big.
2025-01-15 07:24:10 +00:00
Yuya Nishihara
fe86bee64c cargo: bump gix to 0.69.1
The new track_empty flag is set to the default value. It was introduced by the
following commit, and I think the default behavior is good.

d3f5f27732
2025-01-12 10:01:58 +00:00
Benjamin Tan
f02ed0050f lib: dag_walk: fix doc comment typos
This commit fixes more typos unintentionally introduced in d9c68e08,
when renaming `jj branch` to `jj bookmark`.
2025-01-11 16:19:52 +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
f14a6e6f19 git: remove PartialEq requirement from GitPushError
Non-trivial error types usually don't implement Eq/PartialEq.
2025-01-10 01:16:33 +00:00
Yuya Nishihara
720c903b99 git: port s/bookmark/branch/ renames to config migration rules
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
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
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
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-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"
Some checks are pending
binaries / Build binary artifacts (push) Waiting to run
nix / flake check (push) Waiting to run
build / build (, macos-13) (push) Waiting to run
build / build (, macos-14) (push) Waiting to run
build / build (, ubuntu-24.04) (push) Waiting to run
build / build (, windows-latest) (push) Waiting to run
build / build (--all-features, ubuntu-24.04) (push) Waiting to run
build / Build jj-lib without Git support (push) Waiting to run
build / Check protos (push) Waiting to run
build / Check formatting (push) Waiting to run
build / Run doctests (push) Waiting to run
build / Check that MkDocs can build the docs (push) Waiting to run
build / Check that MkDocs can build the docs with latest Python and uv (push) Waiting to run
build / cargo-deny (advisories) (push) Waiting to run
build / cargo-deny (bans licenses sources) (push) Waiting to run
build / Clippy check (push) Waiting to run
Codespell / Codespell (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
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
Some checks are pending
binaries / Build binary artifacts (push) Waiting to run
nix / flake check (push) Waiting to run
build / build (, macos-13) (push) Waiting to run
build / build (, macos-14) (push) Waiting to run
build / build (, ubuntu-latest) (push) Waiting to run
build / build (, windows-latest) (push) Waiting to run
build / build (--all-features, ubuntu-latest) (push) Waiting to run
build / Build jj-lib without Git support (push) Waiting to run
build / Check protos (push) Waiting to run
build / Check formatting (push) Waiting to run
build / Run doctests (push) Waiting to run
build / Check that MkDocs can build the docs (push) Waiting to run
build / Check that MkDocs can build the docs with latest Python and uv (push) Waiting to run
build / cargo-deny (advisories) (push) Waiting to run
build / cargo-deny (bans licenses sources) (push) Waiting to run
build / Clippy check (push) Waiting to run
Codespell / Codespell (push) Waiting to run
website / prerelease-docs-build-deploy (ubuntu-latest) (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
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