482 Commits

Author SHA1 Message Date
Martin von Zweigbergk
b549090acc index: adopt ChangeIdIndex and relatives from revset module
The `ChangeIdIndex` type is currently in defined in the `revset`
module because that's the only placed it's used. However, I'd like to
start using it directly from `index`. The idea is to make it possible
to create a `ChangeIdIndex` given a set of heads, without first
creating a `Revset`.
2024-01-08 06:06:47 -08:00
Yuya Nishihara
31b236a70d object_id: move HexPrefix and PrefixResolution from index module 2024-01-05 10:20:57 +09:00
Yuya Nishihara
dde42b9c05 index: rename resolve_prefix() to resolve_commit_id_prefix()
I'll probably add change id lookup methods to CompositeIndex. The Index trait
won't gain resolve_change_id_prefix(), but I also renamed its resolve_prefix()
for consistency.
2023-12-26 01:03:10 +09:00
Yuya Nishihara
0a1bc2ba42 repo_path: add stub RepoPathBuf type, update callers
Most RepoPath::from_internal_string() callers will be migrated to the function
that returns &RepoPath, and cloning &RepoPath won't work.
2023-11-28 07:33:28 +09:00
Martin von Zweigbergk
6d54afa60e revset: make evaluate_programmatic() optimize expression
It seems generally useful to optimize revset expressions in
`evaluate_programmatic()` so the caller doesn't have to remember to do
it. It should generally be cheap to do so even if it's often not
needed.
2023-11-24 21:13:58 -10:00
Martin von Zweigbergk
550164209c revset: add a RevsetExpression::evaluate_programmatic()
We often resolve a programmatic revset and then immediately evaluate
it. This patch adds a convenience method for those two steps.
2023-11-24 21:13:58 -10:00
Martin von Zweigbergk
f2602f78cf revset: make resolve_programmatic() not return a Result
I think it's always a programming error if `resolve_programmatic()`
returns a `Result`, so it shouldn't have to return a `Result`.
2023-11-24 21:13:58 -10:00
Martin von Zweigbergk
f27f52984e revset: rename resolve() to resolve_programmatic()
`RevsetExpression::resolve()` is meant for programmatically created
expressions. In particular, it may not contain symbols. Let's try to
clarify that by renaming the function and documenting it.
2023-11-24 21:13:58 -10:00
Yuya Nishihara
2ac9865ce7 revset: exclude @git branches from remote_branches()
As discussed in Discord, it's less useful if remote_branches() included
Git-tracking branches. Users wouldn't consider the backing Git repo as
a remote.

We could allow explicit 'remote_branches(remote=exact:"git")' query by changing
the default remote pattern to something like 'remote=~exact:"git"'. I don't
know which will be better overall, but we don't have support for negative
patterns anyway.
2023-11-08 07:34:30 +09:00
Yuya Nishihara
4c4eb31a62 view: add methods that filter local/remote branches by pattern
We'll use them in CLI code.
2023-10-22 04:07:49 +09:00
Yuya Nishihara
f7c8622981 str_util: extract StringPattern filtering iterator from revset module 2023-10-21 09:55:01 +09:00
Yuya Nishihara
2d80f071de str_util: extract function that constructs StringPattern from string 2023-10-21 09:55:01 +09:00
Yuya Nishihara
5707a194d5 str_util: extract StringPattern from revset module
Branch name filtering in CLI will be migrated to this, and I'll probably add
glob:<pattern> in place of --glob option.
2023-10-21 09:55:01 +09:00
Yuya Nishihara
390b3208da revset: always include non-tracking remote branches in suggestion
For the same reason as the previous commit. Non-tracking remote branch
shouldn't be shadowed by a local branch of the same name.
2023-10-17 16:42:36 +09:00
Yuya Nishihara
35ea607abd view: make get_remote_branch() return RemoteRef instead of RefTarget
I'm going to add tracking state to RemoteRef, and we should compare both
target and state in the tests.
2023-10-16 05:12:19 +09:00
Yuya Nishihara
ab1a6e2f71 view: make remote branches iterator yield RemoteRef instead of RefTarget
git::import_refs() will need to read RemoteRef's tracking state.
2023-10-16 05:12:19 +09:00
Yuya Nishihara
e7d93e5bf1 view: turn BranchTarget into borrowed type
This isn't important, but I'm going to change remote_targets to store RemoteRef
instead of RefTarget, so I went ahead and change the other field types as well.
2023-10-16 05:12:19 +09:00
Yuya Nishihara
b7c7b19eb8 view: migrate in-memory structure to per-remote branches map
There's a subtle behavior change. Unlike the original remove_remote_branch(),
remote_views entry is not discarded when the branches map becomes empty. The
reasoning here is that the remote view can be added/removed when the remote
is added/removed respectively, though that's not implemented yet. Since the
serialized data cannot represent an empty remote, such view may generate
non-unique content hash.
2023-10-14 22:20:00 +09:00
Yuya Nishihara
3ec3cac90b revset: use op_store::View type to resolve branches()/remote_branches()
These functions depend heavily on the underlying data structure, and I haven't
decided abstract View API to access to per-remote data types. Let's use the
underlying data type for now.
2023-10-14 22:20:00 +09:00
Yuya Nishihara
d0bc34e0f2 git: look up "git" remote branches normally 2023-10-07 19:33:35 +09:00
Yuya Nishihara
0e82e52c3a revset: remove extra step to resolve full commit id, use prefix matching
Since both has_id() and resolve_prefix() do binary search, their costs are
practically the same. I think has_id() would complete with fewer ops, but such
level of optimization wouldn't be needed here. More importantly, this ensures
that unreachable commits aren't imported by GitBackend::read_commit().
2023-10-07 02:08:36 +09:00
Martin von Zweigbergk
a6ef3f0b6c cli: make set of immutable commits configurable
This adds a new `revset-aliases.immutable_heads()s` config for
defining the set of immutable commits. The set is defined as the
configured revset, as well as its ancestors, and the root commit
commit (even if the configured set is empty).

This patch also adds enforcement of the config where we already had
checks preventing rewrite of the root commit. The working-copy commit
is implicitly assumed to be writable in most cases. Specifically, we
won't prevent amending the working copy even if the user includes it
in the config but we do prevent `jj edit @` in that case. That seems
good enough to me. Maybe we should emit a warning when the working
copy is in the set of immutable commits.

Maybe we should add support for something more like [Mercurial's
phases](https://wiki.mercurial-scm.org/Phases), which is propagated on
push and pull. There's already some affordance for that in the view
object's `public_heads` field. However, this is simpler, especially
since we can't propagate the phase to Git remotes, and seems like a
good start. Also, it lets you say that commits authored by other users
are immutable, for example.

For now, the functionality is in the CLI library. I'm not sure if we
want to move it into the library crate. I'm leaning towards letting
library users do whatever they want without being restricted by
immutable commits. I do think we should move the functionality into a
future `ui-lib` or `ui-util` crate. That crate would have most of the
functionality in the current `cli_util` module (but in a
non-CLI-specific form).
2023-09-25 15:41:45 -07:00
Yuya Nishihara
9697970f71 revset: simplify RevsetAliasesMap getters to not construct id
I originally attempted to embed function parameters in RevsetAliasId. That's
probably why these getters return id. Let's move id construction to callers
since the id only serves as a recursion blocker.
2023-09-24 23:21:23 +09:00
Yuya Nishihara
dde1c1ec9c revset: use ancestors(x, 0) in tree substitution test 2023-09-08 09:28:14 +09:00
James Sully
0946934ca6 revset: Add optional argument n to ancestors() in revset language 2023-09-08 02:50:58 +10:00
James Sully
6ea10906a8 revset: add ancestors_range() method 2023-09-08 02:50:58 +10:00
Yuya Nishihara
c4769e0b7c revset: translate symbol rules in error message
Since we have overloaded operator symbols, we need to deduplicate them
upfront. Legacy and compat operators are also removed from the suggestion.

It's a bit ugly to mutate the error struct before calling Error::renamed_rule(),
but I think it's still better than reimplementing message formatting function.
2023-09-07 15:29:39 +09:00
Yuya Nishihara
a868b2d9a5 revset: do not lookup unimported tags or remote branches by unqualified name
Since e7e49527efdf "git: ensure that remote branches never diverge", the last
known "refs/remotes" ref should be synced with the corresponding remote branch.
So we can always trust the branch@remote expression. We don't need "refs/tags"
lookup either since tags should have been imported by git::import_refs().

FWIW, I'm thinking of reorganizing view.git_refs() map as per-remote views.
It would be nice if we can get rid of revsets and template keywords exposing
low-level Git ref primitives.
2023-09-06 13:42:22 +09:00
Philip Metzger
8dda7e21e0 revsets: Add descendants_at and ancestors_at
They are needed for `next` and `prev`.
They behave symmetrically for parents and children.
2023-09-05 23:13:39 +02:00
Yuya Nishihara
b0c8e9ef62 revset: add 0-ary "::" and ".." operators as short for "all()" and "~root()"
Suppose "x::y" is the operator that defaults to "root()::visible_heads()"
respectively, "::" is identical to "all()". Since we've just changed the
behavior of "..y", ".." is now "root()..visible_heads()" meaning "~root()".
2023-09-05 10:40:04 +09:00
Yuya Nishihara
6b2ad23f8f revset: evaluate "..y" expression to "root()..y"
This seems useful since the root commit is often uninteresting. It's also
consistent with "x::y" in a way that the left operand defaults to "root()".
2023-09-05 10:40:04 +09:00
Yuya Nishihara
f2c1697362 revset: fix comment about "@" expression 2023-09-05 10:40:04 +09:00
Yuya Nishihara
e3c85d6ecc revset: convert root symbol to function
The idea is that we can fully eliminate special symbols that would otherwise
shadow user branches, tags, or change ID prefixes.

Closes #2095
2023-09-04 10:36:30 +09:00
Yuya Nishihara
55c6e90555 git: remove handling of real remote named "git", always override
#1690
2023-08-29 22:50:46 +09:00
Yuya Nishihara
0e26ef7733 git: add constant for pseudo remote name "git" 2023-08-29 22:50:46 +09:00
Yuya Nishihara
79291a3ca4 revset: add separate name@remote node to discriminate it from quoted one
A local branch named "name@remote" no longer shadows a remote branch "name"
at "remote".
2023-08-26 07:47:12 +09:00
Yuya Nishihara
75ebdf69a1 revset: parse @ like operator (but without alias substitution)
This is what I proposed in #2095. @ is now an operator to concatenate symbols.

Unlike the other operators, lhs/rhs of @ is not a target of alias substitution.
'x' in 'x@y' doesn't look like a named variable, though it's technically
possible to allow definition of an alias expanded to a symbol of specific remote
or vice versa. This will probably apply to the kind:pattern syntax, where
aliases are expanded due to the current implementation restriction. I've added
a TODO comment about that.
2023-08-26 07:47:12 +09:00
Yuya Nishihara
8c2baafe5c revset: extract symbol parsing and resolution helper
These helpers will be used by name@remote handling.
2023-08-26 07:47:12 +09:00
Martin von Zweigbergk
c43a3067eb revset: pass all context arguments to parse() via an object
`revset::parse()` already has a `RevsetWorkspaceContext` argument, so
I think it makes sense to put that and the other context arguments
into a larger `RevsetParseContext` object.
2023-08-20 21:30:06 -07:00
Martin von Zweigbergk
5f3df4aaea revset: resolve "@" symbol's workspace id earlier (while parsing)
We resolve file paths into repo-relative paths while parsing the
revset expression, so I think it's consistent to also resolve which
workspace "@" refers to while parsing it. That means we won't need the
workspace context both while parsing and while resolving symbols.

In order to break things like `author("martinvonz@")` (thanks to @yuja
for catching this), I also changed the parsing of working-copy
expressions so they are not allowed to be
quoted. `author(martinvonz@)` will therefore be an error now. That
seems like a small improvement anyway, since we have recently talked
about making `root` and `[workspace]@` not parsed as other symbols.
2023-08-20 17:57:18 -07:00
Martin von Zweigbergk
f9b3211d58 revset: drop an unnecessary return keyword 2023-08-20 17:57:18 -07:00
Yuya Nishihara
b6794ca04a revset: rename literal:"" prefix to exact:""
Per discussion in #2107, I believe "exact" is preferred.

We can also change the default to exact match, but it doesn't always make
sense. Exact match would be useful for branches(), but not for description().
We could define default per predicate function, but I'm pretty sure I cannot
remember which one is which.
2023-08-19 11:33:57 +09:00
Yuya Nishihara
ebdc22a65e revset: add support for explicit substring:"..." prefix
git-branchless calls it a substring, so let's do the same.

FWIW, I copied literal:_ from Mercurial, but it's exact:_ in git-branchless.
I have no idea which one is preferred. Since this feature isn't released, we
can freely change it if exact:_ makes more sense.

https://github.com/arxanas/git-branchless/wiki/Reference:-Revsets#patterns
2023-08-19 10:32:59 +09:00
Yuya Nishihara
4c3265477b revset: remove unused MineWithoutUserName error variant
user_email is always available to the revset parser.
2023-08-17 07:49:24 +09:00
Yuya Nishihara
810d4eeef2 revset: use exact match for mine() 2023-08-17 07:42:12 +09:00
Yuya Nishihara
7da7356ef7 revset: add fast path to look up branches by literal name 2023-08-17 07:42:12 +09:00
Yuya Nishihara
81f1ae38b3 revset: add literal:"string" pattern syntax
The syntax is slightly different from Mercurial. In Mercurial, a pattern must
be quoted like "<kind>:<needle>". In JJ, <kind> is a separate parsing node, and
it must not appear in a quoted string. This allows us to report unknown prefix
as an error.

There's another subtle behavior difference. In Mercurial, branch(unknown) is
an error, whereas our branches(literal:unknown) is resolved to an empty set.
I think erroring out doesn't make sense for JJ since branches() by default
performs substring matching, so its behavior is more like a filter.

The parser abuses DAG range syntax for now. It can be rewritten once we remove
the deprecated x:y range syntax.
2023-08-17 07:42:12 +09:00
Yuya Nishihara
5b3c73dfc4 revset: insert StringPattern enum to add support for other kind of matching 2023-08-17 07:42:12 +09:00
Emily Fox
9ba9ecd708 revset: add function mine() 2023-08-16 11:00:14 -05:00
Martin von Zweigbergk
f1b817e8ca cleanup: fix warnings from nightly clippy 2023-08-14 22:11:56 -07:00