Commit graph

373 commits

Author SHA1 Message Date
Martin von Zweigbergk
33da97f0bf revsets: add iterator adapter for rendering simplified graph of set
When rendering a non-contiguous subset of the commits, we want to
still show the connections between the commits in the graph, even
though they're not directly connected. This commit introduces an
adaptor for the revset iterators that also yield the edges to show in
such a simplified graph.

This has no measurable impact on `jj log -r ,,v2.0.0` in the git.git
repo.


The output of `jj log -r 'v1.0.0 | v2.0.0'` now looks like this:

```
o   e156455ea491 e156455ea491 gitster@pobox.com 2014-05-28 11:04:19.000 -07:00 refs/tags/v2.0.0
:\  Git 2.0
: ~
o c2f3bf071ee9 c2f3bf071ee9 junkio@cox.net 2005-12-21 00:01:00.000 -08:00 refs/tags/v1.0.0
~ GIT 1.0.0
```

Before this commit, it looked like this:

```
o e156455ea491 e156455ea491 gitster@pobox.com 2014-05-28 11:04:19.000 -07:00 refs/tags/v2.0.0
| Git 2.0
| o   c2f3bf071ee9 c2f3bf071ee9 junkio@cox.net 2005-12-21 00:01:00.000 -08:00 refs/tags/v1.0.0
| |\  GIT 1.0.0
```

The output of `jj log -r 'git_refs()'` in the git.git repo is still
completely useless (it's >350k lines and >500MB of data). I think
that's because we don't filter out edges to ancestors that we have
transitive edges to. Mercurial also doesn't filter out such edges, but
Git (with `--simplify-by-decoration`) seems to filter them out. I'll
change it soon so we filter them out.
2021-05-01 14:56:52 -07:00
Martin von Zweigbergk
b953d7d801 git_store: revert lock timeout to 10s
This backs out commit 67e11e0fc3. We now use one thread per CPU in
tests (419002fab4), so I hope the tests won't need the 1-minute
timeout anymore.
2021-05-01 14:40:47 -07:00
Martin von Zweigbergk
df2caab274 tests: add a helper for building commit graphs when only topology is important 2021-04-30 22:46:20 -07:00
Martin von Zweigbergk
419002fab4 tests: use one thread per core in concurrency tests
The tests have been failing in GitHub's CI quite frequently. It's
about time I try to do something about it. Let's see if this helps.
2021-04-29 00:01:04 -07:00
Martin von Zweigbergk
46edbbef09 revsets: add revset function for getting all git refs
This adds a `git_refs()` revset that includes all commits pointed to
by a git ref. It's not very useful yet because the graph log doesn't
use the right type of edges for non-contiguous commits.
2021-04-28 23:34:17 -07:00
Martin von Zweigbergk
f5151bdbbe revsets: add a RevsetIterator type, to simplify API and enable adapters 2021-04-28 23:34:17 -07:00
Martin von Zweigbergk
67ca161f24 cli: key nodes in graphlog by position in index instead of by commit id
This speeds up `jj log -T "" -r ,,v2.0.0` in the git.git repo by about
1.6 dB (~31%).
2021-04-28 23:34:17 -07:00
Martin von Zweigbergk
0145be3693 index: add a newtype wrapper for IndexPosition
It seems better to both hide the specific type and to get some more
type safety.
2021-04-28 23:34:14 -07:00
Martin von Zweigbergk
5b18e89a4d diff: fix LCS when a line/word/byte has been moved later 2021-04-28 23:33:18 -07:00
Martin von Zweigbergk
13134bd5a4 cleanup: address warnings reported by new clippy version 2021-04-28 09:12:48 -07:00
Martin von Zweigbergk
ba4ac44719 cli: replace committer email by author timestamp in log template
I've often missed not having the timestamp there. It gets too long
with both email and timestamp for both author and committer, so I
removed the committer email to make room for the author timestamp.
2021-04-26 21:30:14 -07:00
Martin von Zweigbergk
a04e145f06 cli: make remaining messages start with uppercase for consitency 2021-04-25 12:55:59 -07:00
Martin von Zweigbergk
c6f6498cc9 conflicts: add newline after conflict marker lines
Merging is currently done with line-level granularity, so it makes
sense to have newlines after the markers. That makes them easier to
edit out when resolving conflicts.
2021-04-24 13:53:24 -07:00
Martin von Zweigbergk
f9460e5c52 graphlog: indent long text correctly when edge gets closed 2021-04-23 22:34:34 -07:00
Martin von Zweigbergk
4777421bcf graphlog: close edges on the right when a chain ends
This case is very common in `jj obslog` output and the resulting
graphs are very hard to read.
2021-04-23 22:28:37 -07:00
Martin von Zweigbergk
9dc18524fc revsets: add "ancestor difference" range operator (like git's ..) 2021-04-23 19:10:28 -07:00
Martin von Zweigbergk
49173de423 revsets: add DAG range operator (like hg's infix ::)
This lets you use the same operator as we currently have for ancestors
and descendants (`,,`) to also specify a DAG range. That's what
Mercurial uses the `::` operator for and what Git has `git log
--ancestry-path` for.
2021-04-23 19:10:26 -07:00
Martin von Zweigbergk
d8c209c82a revsets: give parents/children operators higher precedence than range operators 2021-04-23 18:45:42 -07:00
Martin von Zweigbergk
9de5f94af6 revsets: use same error variant for imcomplete parse as for syntax error 2021-04-23 16:59:04 -07:00
Martin von Zweigbergk
0b0374d401 revsets: make parsed Children and Descendants have roots and heads
It seems clearer to let the parsed `RevsetExpression`s have only root
and head expression instead of adding the ancestors when building the
expression tree.
2021-04-23 16:15:17 -07:00
Martin von Zweigbergk
f209354503 revsets: simplify and clarify description revset slightly 2021-04-23 13:30:31 -07:00
Martin von Zweigbergk
145731ec74 revsets: change operators around a bit to prepare for infix DAG range operator
I really liked the idea of having the operators for parents and
ancestors (etc.) look similar, but that turned out to be problematic
when we want to add an infix operator for a DAG range (hg's `::`
revset operator and git's `--ancestry-path` flag). Let's say we chose
`:*:` as the operator. Part of the problem is how to parse `foo:*:bar`
without eagerly parsing the `foo:`. It would also be nicer to use
exactly the same operator as prefix, postfix, and infix. Since the
"parents" operator can be repeated, we can't have it be just `:` and
the "ancestors" operator be `::`. We could make the "ancestors"
operator be something like `*:*` (or anything symmetric with the `:`
symbol on the inside). However, at that point, the operator is getting
ugly and hard to type. Another option would be to use `:` for
ancestors and `::` for parents, but that is counterintuitive and get
annoying if you want to repeat it. So it seems that the best option is
to simply pick different symbols for parents/children and
ancestors/descendants/range.

This patch changes the ancestors/descendants operators to both be
`,,`. I'm not at all attached to that particular symbol. I suspect
we'll change it later.
2021-04-23 11:11:07 -07:00
Martin von Zweigbergk
c894a7435f revsets: make function arguments always be revset expressions
Now that expressions may contain literal strings, we can simply have
functions accept only expressions arguments. That simplifies both the
grammar and the code.

A small drawback is that `description((foo), bar)` is now allowed and
does a search for the string "foo" (not "(foo)"). That seems
unlikely to trip up users.
2021-04-23 10:51:41 -07:00
Martin von Zweigbergk
5819687237 revsets: accept quoted symbol names
Git refs with names containing e.g "-" are currently not accepted
symbol names, and I don't plan to change the grammar to accept
them. Instead, let's have the user quote symbol names containing
unusual characters. That way we can keep these symbols reserved for
revset operators.

With this patch the user can do e.g. `jj diff -r '"v2.9.0-rc2"'`.
2021-04-23 10:37:42 -07:00
Martin von Zweigbergk
d78fd9e979 revsets: add functions and operators for children and descendants
This adds `children(<set>)` and `<set>:` for the children of the given
set, and `descendants(<set>)` and `<set>:*` for the descendants of the
given set. The children and descendants are filtered to be among
ancestors of non-obsolete commits. I haven't added a way of overriding
that yet.
2021-04-21 23:34:20 -07:00
Martin von Zweigbergk
618abf4379 revsets: use consistent "_op" suffix for operator rules in the grammar
This is especially important now that we leak the rule names into the
`SyntaxError` message. For example, the error message when doing `jj
diff -r :` will now mention "expected parents_op, ancestors_op, or
primary". It seems much clearer with the "_op" suffixes there. Longer
term, we should think more about how we can best surface syntax errors
from the library crate.
2021-04-21 18:53:58 -07:00
Martin von Zweigbergk
a4ef42962c revsets: don't crash when given ungrammatical revset
I also snuck in some updates to the test cases.
2021-04-21 18:53:58 -07:00
Martin von Zweigbergk
744f209e76 revsets: move parse-tests to to revset module (from separate test module)
The tests don't need any complex set up (no repo necessary), so they
can be in the `revset` module itself. I'm sure we'll need to split up
that module later (at least separate out the parsing), but that's a
separate problem.
2021-04-21 18:53:58 -07:00
Martin von Zweigbergk
6bc1361b84 index: make revision walk be by position instead of generation number
I don't know why I made it walk by generation number to start
with. Walking by position is better in at least two ways: 1) revsets
now depend on the walks to be by descending index position (though
they could equally well depend on the walks to be by generation number
-- it just needs to be consistent), and 2) the log output gets less
interleaved.

This commit makes the number of bytes in the graphlog output in the
git.git repo drop by ~40% due to the reduced amount of
interleaving. Also, it reduces the time of `jj bench walkrevs v1.0.0
v2.0.0` in the git.git repo by 32% (9.4ms -> 6.4ms) and `jj bench
walkrevs v2.0.0 v1.0.0` by 33% (7.7ms -> 5.1ms).
2021-04-21 18:53:56 -07:00
Martin von Zweigbergk
98f4e24892 cli: make benchmark ids include parameters
It makes no sense to compare a run of `jj walkrevs v1.0.0 v2.0.0` with
a run of `jj walkrevs v2.0.0 v1.0.0`, for example.
2021-04-21 16:56:45 -07:00
Martin von Zweigbergk
64fcf90c68 view: make root commit public 2021-04-18 23:04:15 -07:00
Martin von Zweigbergk
b52cfc156c revsets: add a public_heads() revset function 2021-04-18 22:52:31 -07:00
Martin von Zweigbergk
3a65c1d2ab revsets: add intersection operator 2021-04-18 22:45:12 -07:00
Martin von Zweigbergk
332580918c revsets: add union operator 2021-04-18 22:45:12 -07:00
Martin von Zweigbergk
2ac5d1f912 revsets: allow spaces in most places (but not after prefix operators) 2021-04-18 22:45:12 -07:00
Martin von Zweigbergk
c04f418e67 revsets: add difference operator 2021-04-18 22:45:12 -07:00
Martin von Zweigbergk
e733b074e1 revsets: restructure grammar to prepare for operator precedences 2021-04-18 22:45:12 -07:00
Martin von Zweigbergk
d9ae7cdd6d revsets: allow parenthesized expressions
We'll clearly want to allow parenthesized expressions once we have
infix operators (if not before). Let's prepare by allowing parentheses
already now.
2021-04-18 22:45:12 -07:00
Martin von Zweigbergk
d71c083a7f cli: use revsets also when looking up by description 2021-04-18 22:45:12 -07:00
Martin von Zweigbergk
62f0778942 revsets: add a description() revset
The revset is currently eagerly evaluated, which is clearly bad. We'll
need to fix that later.
2021-04-18 22:45:12 -07:00
Martin von Zweigbergk
563e9eadc0 cli: give jj log a -r option and remove --all
This teaches `jj log` a new `-r` option with a default of
`*:non_obsolete_heads()`. It also removes the `--all` option since
that's not used very frequently and can now be achieved with `jj log
-r '*:all_heads()'`.
2021-04-18 22:45:11 -07:00
Martin von Zweigbergk
cf48d6b6c0 cli: use revsets for walking revisions for log output 2021-04-18 22:45:11 -07:00
Martin von Zweigbergk
05e9149157 revsets: add a non_obsolete_heads() revset
This change adds a `non_obsolete_heads(<set>)` revset, which walks up
ancestors of the input set until it gets to a non-obsolete and
non-pruned commit. That's what we do by default in `jj log`
(i.e. without `--all`). Now we can make `jj log` use revsets and teach
it a `-r` option!
2021-04-18 22:45:10 -07:00
Martin von Zweigbergk
dbfa267d60 cli: remove unnecessary check for checkout when filtering uninteresting heads
When removing uninteresting heads, we had a check for explicitly
keeping the checkout (working copy) commit. I'm pretty sure that is a
leftover from before we had the "pruned" flag on commits; the working
copy should never be pruned or obsolete.
2021-04-18 22:32:38 -07:00
Martin von Zweigbergk
30aa459d2a revsets: add a all_heads() revset function
This adds a `all_heads()` revset function, which contains all heads in
the view, i.e. including non-public heads and obsolete heads.
2021-04-18 22:31:46 -07:00
Martin von Zweigbergk
88904e2b63 revsets: add support for function syntax
This adds `parents(foo)` and `ancestors(foo)` as alternative ways of
writing `:foo` and `*:foo`. 

I haven't added support for for whitespace yet; the parsing is very
strict. The error messages will also need to be improved later.
2021-04-18 21:25:58 -07:00
Martin von Zweigbergk
2d6325b0f4 revsets: define grammar in pest 2021-04-18 21:25:58 -07:00
Martin von Zweigbergk
0d62a336af revsets: initial support for Mercurial-style revsets
This patch adds initial support for a DSL for specifying revisions
inspired by Mercurial's "revset" language. The initial support
includes prefix operators ":" (parents) and "*:" (ancestors) with
naive parsing of the revsets. Mercurial uses postfix operator "^" for
parent 1 just like Git does. It uses prefix operator "::" for
ancestors and the same operator as postfix operator for descendants. I
did it differently because I like the idea of using the same operator
as prefix/postfix depending on desired direction, so I wanted to apply
that to parents/children as well (and for
predecessors/successors). The "*" in the "*:" operator is copied from
regular expression syntax. Let's see how it works out. This is an
experimental VCS, after all.

I've updated the CLI to use the new revset support.

The implementation feels a little messy, but you have to start
somewhere...
2021-04-18 21:25:51 -07:00
Martin von Zweigbergk
7861968f64 index: make IndexRef::entry_by_id() etc return entry with repo's lifetime
It's useful to be able to know that given a `repo: RepoRef<'a>`, the
the lifetime of `repo.index().entry_by_id()` will also be `'a`.
2021-04-15 07:00:04 -07:00
Martin von Zweigbergk
209c62075e cli: disallow pushing open commit 2021-04-15 06:55:43 -07:00