ok/jj
1
0
Fork 0
forked from mirrors/jj
Commit graph

2823 commits

Author SHA1 Message Date
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
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
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
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
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
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
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
Martin von Zweigbergk
0bbebaf4f9 rewrite: move calculation of set to rebase to MutableRepo
This lets us make `parent_mapping` private again.
2024-04-15 07:09:12 -07:00
Martin von Zweigbergk
53a0e23759 rewrite: move functions for updating refs to MutableRepo
The functions now depend only on `MutableRepo`, so I think they belong
on that type. This gets us closer to being able to make
`parent_mapping` private again.
2024-04-15 07:09:12 -07:00
Martin von Zweigbergk
f716116249 rewrite: remove unnecessary assertions
I think the recent refactorings (especially 9c382fd8c6) make it
pretty clear that `DescendantRebaser` will not attempt to rebase the
same commit twice, so I think we can remove the assertions. This
removes some of the places where `DescendantRebaser` reaches into
`MutableRepo`'s internals.
2024-04-15 07:09:12 -07:00
Martin von Zweigbergk
656250d6d0 rewrite: pass UserSettings into update_all_references()
With this change, `update_all_references()` only uses `self` to get to
`mut_repo`. I'll move the function onto `MutableRepo` next.
2024-04-15 07:09:12 -07:00
Martin von Zweigbergk
750002594e rewrite: inline and rewrite ref_target_update()
I rewrote `old_target` and `new_target` to more accurately represent
the change; the old target should be a normal (singleton) ref.
2024-04-15 07:09:12 -07:00
Martin von Zweigbergk
f696f5b727 rewrite: leverage root_id() helper on commit object 2024-04-15 07:09:12 -07:00
Martin von Zweigbergk
0525dc9d86 politics: delete references to Pijul
The Pijul maintainer has opinions that I don't understand about how we
mention Pijul (they consider the current mentions offensive as
"bashing Pijul"). Let's just remove the references so we don't have to
deal with it. I think the references to Darcs we already had in most
of these places are sufficient.
2024-04-14 13:16:08 -07:00
Yuya Nishihara
aaa2025dfc git: on fetch, pin visible untracked remote refs
This implements the other workaround described in 57167cefda "git: on
import_refs(), don't abandon ancestors of newly fetched refs":

> I think there are two ways to fix the problem:
>  a. pin non-tracking remote branches just like local refs
>  b. pin newly fetched refs in addition to local refs
> This patch implements (b) because it's simpler and more obvious that the
> fetched commits would never be abandoned immediately.

The idea of (a) is that untracked remote branches are independent read-only
refs, and read-only branches shouldn't be rewritten implicitly. Once the
branch gets rewritten or abandoned by user, these remote refs will be hidden,
and won't be pinned anymore.

Since (a) effectively supersedes (b), this patch also removes the original
workaround.

Fixes #3495
2024-04-14 11:38:21 +09:00
dploch
57a5d7dd64 cli_util: support multiple extensions consistently
If we ever implement some sort of ABI for dynamic extension loading, we'll need these underlying APIs to support multiple extensions, so we might as well do that first.
2024-04-12 14:07:33 -04:00
Yuya Nishihara
30984dae4a cli: if enabled, parse path arguments as fileset expressions
If this doesn't work out, maybe we can try one of these:
 a. fall back to bare file name if expression doesn't contain any operator-like
    characters (e.g. "f(x" is an error, but "f x" can be parsed as bare string)
 b. introduce command-line flag to opt in (e.g. -e FILESET)
 c. introduce pattern prefix to opt in (e.g. set:FILESET)

Closes #3239, #2915, #2286
2024-04-12 11:36:40 +09:00
Ilya Grigoriev
8fa256ebac New jj debug watchman status command
This command checks not only whether Watchman works, but also whether
it's enabled in the config. Also, the output is easier to understand
than that of the other `jj debug watchman` commands.

It would be nice if `jj debug watchman` called `jj debug watchman
status`, but it's not trivial in `clap` to have a default subcommand.
2024-04-11 10:55:59 -07:00
Yuya Nishihara
33beb8d456 fileset: add recursive iterator over explicit paths
The primary use case is to warn unmatched paths. I originally thought paths in
negated expressions shouldn't be checked, but doing that seems rather
inconsistent than useful. For example, "~x" in "jj split '~x'" should match at
least one file to split to non-empty revisions.
2024-04-11 00:51:19 +09:00
Yuya Nishihara
57b423e3d7 fileset: relax identifier rule to accept more path-like strings
Since fileset is primarily used in CLI, it's better to avoid inner quoting if
possible. For example, ".." would have to be quoted in the original grammar
derived from the revset.

This patch also adds a stricter version of an identifier rule. If we add a
symbol alias, it will follow the "strict_identifier" rule.
2024-04-09 20:42:09 +09:00
Yuya Nishihara
653173abad fileset: implement name resolution stage, add all()/none() functions
#3239
2024-04-09 20:42:09 +09:00
Yuya Nishihara
9c28fe954c fileset: add grammar and implement parser (without name resolution)
The fileset grammar is basically a stripped-down version of the revset grammar,
with a few adjustments:

 * extract function call to "function" rule (like templater)
 * inline "symbol" rule (because "identifier" and "string" should be treated
   differently at the early parsing stage.)

The parser will have a separate name resolution stage. This will help to do
alias substitution properly. I'll probably rewrite the revset parser in the
same way. It will also help if we want to embed fileset expression in file()
revset.
2024-04-09 20:42:09 +09:00
Yuya Nishihara
521bcd81ab dsl_util: deduplicate collect_similar() from revset and templater
For convenience, sort and dedup are done by collect_similar().
2024-04-09 20:42:09 +09:00
Evan Mesterhazy
379849b4b8 Fix documentation for RevsetExpression::ancestors_at and descendants_at
The current documentation is wrong. This is a follow up for
https://github.com/martinvonz/jj/pull/3461#discussion_r1555011289
2024-04-08 08:29:14 -04:00
Yuya Nishihara
73508730aa revset: rewrite identifier rule in common infix-op rule pattern
I don't remember why I made it defined recursively, but it's basically the
same as "primary ~ (infix_op ~ primary)*" rule.
2024-04-08 00:37:25 +09:00
Yuya Nishihara
7f1f73b0fa revset: move whitespace rule to top
The whitespace rule is a bit special, and it seemed weird that the rule is
defined between literals and operator tokens.
2024-04-08 00:37:25 +09:00
Yuya Nishihara
c8f93c50fc revset: remove redundant Result<..> from parse_symbol_rule_as_literal() 2024-04-08 00:37:25 +09:00
Yuya Nishihara
d442cd872f revset: backport \-escapes parsing from templater 2024-04-08 00:37:25 +09:00
Yuya Nishihara
d1ae2d72c8 revset: rename Rule::literal_string to string_literal 2024-04-08 00:37:25 +09:00
Yuya Nishihara
274183fa66 dsl_util: extract helper that parses string literal with \-escapes
The top-level assertion is removed since it's now obvious that the pair
represents a Rule::string_literal.
2024-04-08 00:37:25 +09:00