Commit graph

6010 commits

Author SHA1 Message Date
Evan Mesterhazy
3d267de53e Use CommitIteratorExt to replace .map(|c| c.id().clone())
This replaces `.map(|c| c.id().clone())` with `.ids().cloned()` to use nicer
syntax for getting `CommitId`s from an iterator of commits using the
`CommitIteratorExt` trait.

In one case we can actually call `.parent_ids()` directly. I also pluralized a
variable to make it clearer that it's a vec of IDs and not a single ID.
2024-04-19 08:16:42 -04:00
Martin von Zweigbergk
449fc423b8 parallelize: drop redundant "Nothing changed." case
The rewritten code is already a no-op when there's a single input. I
don't think the case is common enough to warrant having a special case
for performance reasons either. Also, by not having the special case,
`jj parallelize <immutable commit>` fails consistently with the
non-singleton case.
2024-04-18 21:06:52 -07:00
Martin von Zweigbergk
89356aebc6 parallelize: make the command pass in more cases
The checks are not needed by the new implementation, so just drop
them.
2024-04-18 21:06:52 -07:00
Martin von Zweigbergk
860b39b80f parallelize: include parents in template for all tests
Should make it easier to understand the graph shape when there are
lots of crossing lines.
2024-04-18 21:06:52 -07:00
Martin von Zweigbergk
fe57602b03 tests: avoid a future ancestor merge with root commit
I'm going to make some `jj parallelize` cases that currently error out
instead be successful. Some of the will result in ancestor merges with
the root commit. This patch updates those tests to avoid that.
2024-04-18 21:06:52 -07:00
Martin von Zweigbergk
e0a32d4809 parallelize: don't rewrite commits that keep their parents
The new API makes it easy to leave commits in place if their parents
didn't change, so let's do that.
2024-04-18 21:06:52 -07:00
Martin von Zweigbergk
d6b41c18c9 parallelize: rewrite using transform_descendants()
`jj parallelize` was a good example of a command that can be
simplified by the new API, so I decided to rewrite it as an example.

The rewritten version is more flexible and doesn't actually need the
restrictions from the old version (such as checking that the commits
are connected). I still left the check for now to keep this patch
somewhat small. A subsequent commit will remove the restrictions.
2024-04-18 21:06:52 -07:00
Martin von Zweigbergk
e682543570 repo: take owned commit IDs to MutableRepo::new_parents()
We always call `.to_vec()` on the slice, so let's just have the caller
pass in an owned vector instead.
2024-04-18 21:06:52 -07:00
Martin von Zweigbergk
87c65ee0f9 rewrite: make CommitRewriter::replace_parents() remove repeats 2024-04-18 21:06:52 -07:00
Martin von Zweigbergk
96f5ca47d4 repo: add method for tranforming descendants, use in rebase_descendants()
There are several existing commands that would benefit from an API
that makes it easier to rewrite a whole graph of commits while
transforming them in some way.

`jj squash` is one example. When squashing into an ancestor, that
command currently rewrites the ancestor, then rebases descendants, and
then rewrites the rewritten source commit. It would be better to
rewrite the source commit (and any descendants) only once.

Another example is the future `jj fix`. That command will want to
rewrite a graph while updating the trees. There's currently no good
API for that; you have to manually iterate over descendants and
rewrite them.

This patch adds a new `MutableRepo::transform_descendants()` method
that takes a callback which gets a `CommitRewriter` passed to it. The
callback can then decide to change the parents, the tree, etc. The
callback is also free to leave the commit in place or to abandon it.

I updated the regular `rebase_descendants()` to use the new function
in order to exercise it. I hope we can replace all of the
`rebase_descendant_*()` flavors later.

I added a `replace_parent()` method that was a bit useful for the test
case. It could easily be hard-coded in the test case instead, but I
think the method will be useful for `jj git sync` and similar in the
future.
2024-04-18 21:06:52 -07:00
Yuya Nishihara
18f94bbb8b cli: suggest root:"<path>" if cwd-relative path is not in workspace
Closes #3216
2024-04-19 09:35:47 +09:00
dependabot[bot]
d45cf30250 github: bump actions/upload-artifact in the github-dependencies group
Bumps the github-dependencies group with 1 update: [actions/upload-artifact](https://github.com/actions/upload-artifact).


Updates `actions/upload-artifact` from 4.3.1 to 4.3.2
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](5d5d22a312...1746f4ab65)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-18 14:49:04 -05:00
dependabot[bot]
844a8ad9b5 cargo: bump syn from 2.0.59 to 2.0.60 in the cargo-dependencies group
Bumps the cargo-dependencies group with 1 update: [syn](https://github.com/dtolnay/syn).


Updates `syn` from 2.0.59 to 2.0.60
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.59...2.0.60)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-18 15:20:02 +00:00
Martin von Zweigbergk
d38228d0c5 rewrite: move check for unchanged parents onto CommitRewriter 2024-04-18 08:08:51 -07:00
Martin von Zweigbergk
ad1ee2d1d2 rewrite: pass root commits into find_descendants_to_rebase()
I'm going to add another caller that wants to rebase from given roots
instead.
2024-04-18 08:08:51 -07:00
Martin von Zweigbergk
a5e6b1f997 rewrite: inline specialized rebase_commit_with_options() in rebase()
`rebase_commit_with_options()` now does very little, and we don't want
most of it in `rebase()`.
2024-04-18 08:08:51 -07:00
Martin von Zweigbergk
2859277941 rewrite: pass CommitRewriter into rebase_commit_with_options()
`CommitRewriter` wraps 3 of the arguments, so I think it makes sense
to pass it instead. More importantly, I hope to continue refactoring
so many of the callers already have a `CommitRewriter`.
2024-04-18 08:08:51 -07:00
Martin von Zweigbergk
b2993f2b23 rewrite: add rebase() method to CommitRewriter
The new `rebase()` method is meant to be called after deciding on the
new parents (typically by leaving them unchanged). It returns a
`CommitBuilder` for setting any additional values.

There will probably be a `reparent()` method in the future.
2024-04-18 08:08:51 -07:00
Martin von Zweigbergk
b13cb8db26 rewrite: make EmptyBehavior implement Copy 2024-04-18 08:08:51 -07:00
Martin von Zweigbergk
402d94dbd7 rewrite: add a method for simplifying ancestors to CommitRewriter 2024-04-18 08:08:51 -07:00
Martin von Zweigbergk
dc6c7a98d6 rewrite: create a helper type for rewriting commits
This patch adds a struct that's meant to help when rewriting
commits. It contains the old commits and the new parents. I hope to
move most of the logic from `rebase_commit_with_options()` onto it in
coming patches. Then this type can be passed in a callback to make it
easier to do custom rewriting of commits that is currently hard to do
because `rebase_descendants()` does not give the caller any control
over the process.

The helper is similar to `CommmitBuilder`, but it is a bit different
by also embedding information about the source commit, so I don't
think the API would be as convenient if we just used `CommitBuilder`
directly.
2024-04-18 08:08:51 -07:00
Martin von Zweigbergk
ef766d231e cargo: upgrade gix from 0.61.0 to 0.62.0
This upgrade includes a fix for
https://github.com/advisories/GHSA-rrjw-j4m2-mf34
2024-04-18 02:50:13 -07:00
Ilya Grigoriev
9fa01e0246 lib git.rs: minor simplification, fixup to 62b14e1f
As suggested by @yuja in
https://github.com/martinvonz/jj/pull/3516#discussion_r1568466814
2024-04-17 19:51:57 -07:00
Yuya Nishihara
7fded98e40 cli: remove redundant elided node expression from builtin node templates 2024-04-18 11:14:28 +09:00
Yuya Nishihara
1b3bcedd53 cli: label log/obslog template as "log"
It was removed at 522025e091 "log: remove unused and inconsistent `log`
label", but obslog had the same inconsistency. Since it's now easy to label
the template output, let's re-add the "log" label.

The change in test_templater_upper_lower() is noop. Formatter no longer
emits reset sequence in the middle because the template is still labeled.
2024-04-18 11:14:28 +09:00
Yuya Nishihara
6da9167585 cli: set "node" template labels globally
These labels could be renamed to "log_node"/"op_log_node" for consistency, but
I'm not sure if that's a good idea. A single "node" namespace is practically
more convenient.
2024-04-18 11:14:28 +09:00
Yuya Nishihara
2cf40adf02 templater: add template.labeled() for convenience
It's not uncommon to label the whole template output with command or template
name. If the output doesn't have to be captured, we can simply push the label
to the formatter. cmd_config_list() is an example of such cases, but it's also
migrated for consistency.
2024-04-18 11:14:28 +09:00
Yuya Nishihara
610e310112 templater: extract formatting function from LabelTemplate 2024-04-18 11:14:28 +09:00
Yuya Nishihara
4474577ceb fileset: parse cwd/root-glob patterns
Mercurial appears to resolve cwd-relative path first, so "glob:*.c" could be
parsed as "**/*.c" if cwd was literally "**". It wouldn't practically matter,
but isn't correct. Instead, jj's parser first splits glob into literal part
and pattern. That's mainly because we want to parse the user input texts into
type-safe objects, and (RepoPathBuf, glob::Pattern) pairs are the simplest
ones. The current parser can't handle patterns like "foo/*/.." (= "foo" ?),
and errors out. I believe this restriction is acceptable.

Unlike literal paths, the 'glob:' pattern anchors to the whole file path. I
don't think "prefix"-matching glob is useful, and making it the default would
be rather confusing.
2024-04-18 11:09:54 +09:00
Yuya Nishihara
147668cdf2 matchers: add matcher for glob patterns
Patterns are specified as (dir, pattern) pairs because we need to handle
parse errors prior to constructing a matcher, and it's convenient to split
literal directory paths there.
2024-04-18 11:09:54 +09:00
Ilya Grigoriev
62b14e1fa2 lib git.rs: remove workaround for a now-fixed libgit2 bug
https://github.com/libgit2/libgit2/issues/3178 is now fixed.
2024-04-17 12:00:37 -07:00
dependabot[bot]
a500fe36b5 cargo: bump the cargo-dependencies group with 2 updates
Bumps the cargo-dependencies group with 2 updates: [proc-macro2](https://github.com/dtolnay/proc-macro2) and [serde](https://github.com/serde-rs/serde).


Updates `proc-macro2` from 1.0.80 to 1.0.81
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.80...1.0.81)

Updates `serde` from 1.0.197 to 1.0.198
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.197...v1.0.198)

---
updated-dependencies:
- dependency-name: proc-macro2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-dependencies
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-17 09:48:21 -07:00
Martin von Zweigbergk
93baff0b8a rewrite: pass just IDs of new parents into rewrite::rebase*()
It's cheap to look up commits again from the cache in `Store` but it
can be expensive to look up commits we didn't end up needing. This
will make it easier to refactor further and be able to cheaply set
preliminary parents for a rewritten commits and then let the caller
update them.
2024-04-17 06:13:54 -07:00
Martin von Zweigbergk
057b7c8d0b rewrite: take commit and new parents by value in rebase_commit()
I'm going to add a helper struct to help with rewriting commits. I
want to make that struct own the old commit and the new parents to
simplify lifetimes. This patch prepares for that by passing the
commits by value to `rebase_commit()`.
2024-04-17 06:13:54 -07:00
Martin von Zweigbergk
dca9c6f884 repo: propagate errors from find_descendants_to_rebase() 2024-04-17 06:13:54 -07:00
dependabot[bot]
87c4a2e46b cargo: bump serde_json in the cargo-dependencies group
Bumps the cargo-dependencies group with 1 update: [serde_json](https://github.com/serde-rs/json).


Updates `serde_json` from 1.0.115 to 1.0.116
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.115...v1.0.116)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-16 21:32:18 +02:00
Martin von Zweigbergk
8ce099470b cargo: explicitly indicate paths to publish
Running `cargo publish` from a non-colocated repo (such as my usual
repo) is currently quite scary because it uploads all non-hidden
files, even if they're ignored by `.gitignore`
(https://github.com/rust-lang/cargo/issues/2063). I noticed this a
while ago and have always run the command from a fresh clone since
then. To avoid the need for that, let's use the workaround mentioned
on the bug, which is to explicitly list patterns we want to publish.
2024-04-15 20:37:00 -07:00
Martin von Zweigbergk
955c9bf27b jj-lib-proc-macros: add missing LICENSE file
We publish this crate on crates.io, so it should have a LICENSE file.
2024-04-15 20:37:00 -07:00
Evan Mesterhazy
fc49d35daa Fix empty files can't be selected in the builtin diff editor
This fixes several issues that made working with empty files difficult using
the builtin diff editor.

1. The scm-record library used for the editor expects each file to have at
least one section. For new empty files this should be a file mode section. jj
wasn't rendering this mode section, which prevented empty files from being
selected at all.

2. The scm-record library returns `SelectedContents::Absent` if the file has no
contents after the diff editor is invoked. This can be because of several
reasons: 1) the file is new and empty; 2) the file was empty before and is
still empty; 3) the file has been deleted. Perhaps this is a bug in scm-record
and it should return `SelectedContents::Unchanged` or
`SelectedContents::Present` if the file hasn't been deleted. Until this is
patched upstream, we can work around it by disambiguating these cases.

See https://github.com/arxanas/scm-record/issues/26 for the upstream bug.


Fixes #3016
2024-04-15 23:28:06 -04:00
Yuya Nishihara
c147125ce9 cli: migrate "cat" to matcher API, warn unmatched paths
This is the last non-debug command that doesn't support file patterns. It
wouldn't make much sense to "cat" multiple files (despite the command name),
but doing that should be harmless.
2024-04-16 10:12:31 +09:00
Yuya Nishihara
ac794e560f cli: extract function that prints multiple file contents
Prepares for migrating to the matcher API. "Path exists but is not a file"
error is turned into a warning because the loop shouldn't terminate there.

"No such path" error message is also updated for consistency.
2024-04-16 10:12:31 +09:00
Yuya Nishihara
7bed5dd222 matchers: turn RepoPathTree into generic map-like type
This prepares for adding glob matcher, which will be backed by
RepoPathTree<Vec<glob::Pattern>>.

FilesNodeKind/PrefixNodeKind are basically boolean types, but implemented as
enums for better code readability.
2024-04-16 10:10:09 +09:00
Yuya Nishihara
10f5540b3b matchers: rewrite RepoPathTree::to_visit_sets() to not depend on is_dir flag
The is_dir flag will be removed soon. Since FilesMatcher doesn't set is_dir
flag explicitly, is_dir is equivalent to !entries.is_empty(). OTOH,
PrefixMatcher always sets is_dir, so all tree nodes are directories.
2024-04-16 10:10:09 +09:00
Yuya Nishihara
e0d5217450 matchers: inline RepoPathTree::get_visit_sets() 2024-04-16 10:10:09 +09:00
Yuya Nishihara
8e196d0025 matchers: simply derive Default for RepoPathTree
Perhaps, I didn't do that because it's important to initialize is_dir/file to
false. Since I'm going to extract a generic map-like API, and is_dir/file will
be an enum, this won't be a problem.
2024-04-16 10:10:09 +09:00
Yuya Nishihara
f92e5b911f matchers: inline RepoPathTree::add_file() 2024-04-16 10:10:09 +09:00
Yuya Nishihara
0153cc1bc7 matchers: remove tests that directly modify RepoPathTree
I'm going to extract generic map from RepoPathTree, and .get_visit_sets()
will be inlined into FilesMatcher/PrefixMatcher. These removed tests should
be covered by the corresponding matcher tests.
2024-04-16 10:10:09 +09:00
Yuya Nishihara
9a83338079 matchers: don't allow dead_code 2024-04-16 10:10:09 +09:00
Anton Älgmyr
af185725a1 Move to inline labeling and building a single label in log node template. 2024-04-15 22:21:31 +02:00
Anton Älgmyr
2af590eb54 Add template aliases with node symbol configs. 2024-04-15 22:21:31 +02:00