The templater implementation of FoldableExpression is a stripped-down version
of expand_node(). It's visitor-like because I'm going to write generic alias
substitution rules over abstract expression types (template, revset, fileset.)
Naming comes from rustc.
https://rust-unofficial.github.io/patterns/patterns/creational/fold.html
This is basically the same as the previous patch, but for error types. Some
of these functions could be encoded as "E: From<AliasExpandError<'i>>", but
alias substitution logic is recursive, so it would have to convert E back and
force.
Perhaps, the original intent was to abandon non-empty working-copy commit
assuming it was rewritten by git (therefore it should be superseded by the
current working-copy content.) However, there are other reasons that could
make the HEAD out of sync (including concurrent jj operations), and abandoning
non-empty commit can be a disaster. This patch turns it to safer side, and let
user abandon non-empty commit manually.
Fixes#3747
I'm going to extract generic alias substitution functions, and these AST types
will be accessed there. Revset parsing will also be migrated to the generic
functions.
This will help extract common FunctionCallNode<'i, T> type. We don't need
freedom of arbitrary error type choices, but implementing From<_> is the
easiest option I can think of. Another option is to constrain error type by
the expression type T through "T::ParseError: ArgumentsParseError" or
something, but it seemed a bit weird that we have to use trait just for that.
"config list NAME" argument is now parsed as TOML key, but it's still broken
since config.get() expects a query expression in different syntax.
The other config commands will be migrated later.
I add them as aliases, since a user may instead choose to define `immutable_heads()`, for example, as `heads(immutable())`, and the define `immutable()` instead.
This means that <https://martinvonz.github.io/jj/latest/index.html> will
not longer redirect to
<https://martinvonz.github.io/jj/v0.18.0/index.html> (or similar) after
the next release, as requested by @jyn514 on Discord. Instead, it will
be a copy.
Originally, the plan was to use mike's symlink functionality and make
`latest` a symlink. See a comment inline for how that didn't work; we
could do that after changing how GitHub Pages are built.
Before the next `jj` release, and after this PR is merged, you can play
with this by going to <https://martinvonz.github.io/jj/main/> which is
an alias for <https://martinvonz.github.io/jj/prerelease/>.
Because of previous commits in this PR, the latest version will be
marked in the version selector as "latest", so hopefully this won't
confuse users.
Due to the parent commit, the "latest" URL will be considered canonical.
See https://github.com/martinvonz/jj/pull/3723 for a screenshot.
This will make it clearer to the users that the "latest" and "v0.??.?"
are the same even if the former does not redirect to the latter (but has
identical contents).
MkDocs material lists the *first* alias for each version, so I also
added a "nightly" alias for "prerelease". Otherwise, users would see the
"main" alias, and might get confused whether they should use "latest" or
"main" docs if they don't realize it's named after the "main" branch.
(Upon testing, it still shows "main" for now, but it should be possible
to fix this after this PR is merged by reordering the aliases directly
in `versions.json` on the gh-pages branch)
This revset correctly implements "reachability" from a set of source commits following both parent and child edges as far as they can go within a domain set. This type of 'bfs' query is currently impossible to express with existing revset functions.
This follows up on https://github.com/martinvonz/jj/pull/3459 and adds a
label to the closing delimeter of each conflict, e.g. "Conflict 1 of 3
ends".
I didn't initially put any label at the ending delimeter since the
starting delimeter is already marked with "Conflict 1 of 3". However,
I'm now realizing that when I resolve conflicts, I usually go from top
to bottom. The first thing I do is delete the starting conflict
delimeter. It is when I get to the *end* of the conflict that I wonder
whether there are any more conflicts left in the file.