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

46 commits

Author SHA1 Message Date
Yuya Nishihara
a382e96168 revset_graph: place new heads as close to fork point as possible
The idea is simple. New heads are ignored until the node dependency resolution
stuck. Then, only the first head that will unblock the visit will be queued.

Closes #242
2023-07-25 01:45:37 +09:00
Yuya Nishihara
fb33620f9e revset_graph: group commits topologically
The original idea was similar to Mercurial's "topo" sorting, but it was bad
at handling merge-heavy history. In order to render merges of topic branches
nicely, we need to prioritize branches at merge point, not at fork point.
OTOH, we do also want to place unmerged branches as close to the fork point
as possible. This commit implements the former requirement, and the latter
will be addressed by the next commit.

I think this is similar to Git's sorting logic described in the following blog
post. In our case, the in-degree walk can be dumb since topological order is
guaranteed by the index. We keep HashSet<CommitId> instead of an in-degree
integer value, which will be used in the next commit to resolve new heads as
late as possible.

https://github.blog/2022-08-30-gits-database-internals-ii-commit-history-queries/#topological-sorting

Compared to Sapling's beautify_graph(), this is lazy, and can roughly preserve
the index (or chronological) order. I tried beautify_graph() with prioritizing
the @ commit, but the result seemed too aggressively reordered. Perhaps, for
more complex history, beautify_graph() would produce a better result. For my
wip branches (~30 branches, a couple of commits per branch), this works pretty
well.

#242
2023-07-25 01:45:37 +09:00
Yuya Nishihara
d3c031b277 tests: add helper method to capture both stdout/stderr outputs
This pattern is common, and should have a shorthand so that we can easily
add warning messages.
2023-07-03 22:03:05 +09:00
Yuya Nishihara
d6f1ab697a cli: load revset/template aliases in order of config layers
Since we abuse TOML table syntax to define function aliases, an identical
function alias can be found more than once in the merged config. The merged
config doesn't preserve the definition order, so we need to load aliases
table per layer.
2023-05-23 14:20:55 +09:00
Ilya Grigoriev
0e2579ee6a Switch graph node to use for commit instead of
This follows up on 5c703aeb03.

The only reason for this change is that, subjectively, the result looks better to me. I'm not sure why, but I couldn't get used to the old symbol in spite of its seeming reasonableness. It felt really bold and heavy.

If people agree, we can wait until we need to update the screenshots for some other reason before merging this. Sorry I didn't figure this out while the discussion about the referenced commit was going on.

I'm not 100% certain how many fonts support each symbol. Please try it out and let me know if it doesn't work for you.

Compare after:

![image](https://user-images.githubusercontent.com/4123047/229251383-563b889d-7233-42e2-a3c5-bf9368a4d1fd.png)

and before:

![image](https://user-images.githubusercontent.com/4123047/229251695-7fd0ff2c-2832-4262-ade5-5120288cccdf.png)
2023-04-02 23:15:37 -07:00
Yuya Nishihara
998727266c templater: add join method to mapped template 2023-03-18 12:04:00 +09:00
Yuya Nishihara
3124444d24 templater: add list.map(|x| ...) operation
This involves a little hack to insert a lambda parameter 'x' to be used at
keyword position. If the template language were dynamically typed (and were
interpreted), .map() implementation would be simpler. I considered that, but
interpreter version has its own warts (late error reporting, uneasy to cache
static object, etc.), and I don't think the current template engine is
complex enough to rewrite from scratch.

.map() returns template, which can't be join()-ed. This will be fixed later.
2023-03-18 12:04:00 +09:00
Yuya Nishihara
1c0bde1a2b templater: add parsing rule for lambda expression
A lambda expression will be allowed only in .map() operation. The syntax is
borrowed from Rust closure.

In Mercurial, a map operation is implemented by context substitution. For
example, 'parents % "{node}"' prints parents[i].node for each. There are two
major problems: 1. the top-level context cannot be referred from the inner map
expression. 2. context of different types inserts arbitrarily-named keywords
(e.g. a dict type inserts "{key}" and "{value}", but how we could know.)

These issues should be avoided by using explicitly named parameters.

    parents.map(|parent| parent.commit_id ++ " " ++ commit_id)
                                                    ^^^^^^^^^ global keyword

A downside is that we can't reuse template fragment in map expression. Suppose
we have -T commit_summary, -T 'parents.map(commit_summary)' doesn't work.

    # only usable as a top-level template
    'commit_summary' = 'commit_id.short() ++ " " ++ description.first_line()'

Another problem is that a lambda expression might be confused with an alias
function.

    # .map(f) doesn't work, but .map(g) does
    'f(x)' = 'x'
    'g' = '|x| x'
2023-03-18 12:04:00 +09:00
Yuya Nishihara
0bbf146469 templater: unify variants of type error as general expression error
I'm going to add a lambda expression, and the current type-error message
wouldn't work for the lambda type. I also renamed "argument" to "expression"
as the expect_<type>() helper may be called against any expression node.
2023-03-16 03:46:54 +09:00
Yuya Nishihara
f6b0b7788e templater: unify variants of argument count error, embed function name
This is similar to the structure of RevsetParseError. It's unlikely we would
need to discriminate parsing errors, so let's avoid wasting time on naming
things.
2023-03-16 03:46:54 +09:00
Yuya Nishihara
86318bf530 templater: add timestamp.format() method
A format string is parsed statically due to error handling restriction.
I think it covers almost all use cases.
2023-03-15 12:14:42 +09:00
Martin von Zweigbergk
5c703aeb03 cli: replace o as graph node by when using unicode graph
@joyously found `o` confusing because it's a valid change id prefix. I
don't have much preference, but `●` seems fine. The "ascii",
"ascii-large", and "legacy" graph styles still use "o".

I didn't change `@` since it seems useful to have that match the
symbol used on the CLI. I don't think we want to have users do
something like `jj co ◎-`.
2023-03-12 23:21:05 -07:00
Yuya Nishihara
c52efd9df3 templater: add fill(width, content) function
The parameter order follows indent()/label() functions, but this might be
a bad idea because fill() is more likely to have optional parameters. We can
instead add template.fill(width) method as well as .indent(prefix). If we take
this approach, we'll probably need to add string.fill()/indent() methods,
and/or implicit cast at method resolution. The good thing about the method
syntax is that we can add string.refill(), etc. for free, without inventing
generic labeled template functions.

For #1043, I think it's better to add a config like ui.log-word-wrap = true.
We could add term_width/graph_width keywords to the templater, but the
implementation would be more complicated, and is difficult to use for the
basic use case. Unlike Mercurial, our templater doesn't have a context map
to override the graph_width stub.
2023-03-10 16:07:55 +09:00
Yuya Nishihara
e8fd12aff6 templater: add list.join(separator) method
The implementation is a bit tricky since we have to combine a property
(of C -> Vec<Template<()>> type) and a separator of Template<C> type.
2023-03-10 12:58:32 +09:00
Yuya Nishihara
6c146de2e8 templater: add string.lines() method
This wouldn't be used much in practice, but is useful for writing tests of
list methods.
2023-03-10 12:58:32 +09:00
Yuya Nishihara
8f8a9c91bc templater: add indent(prefix, content) function
The argument order is different from Mercurial's indent() function. I think
indent(prefix, content) is more readable for lengthy content. However,
indent(content, prefix, ...) might be better if we want to add an optional
firstline_prefix argument.
2023-03-04 12:10:53 +09:00
Yuya Nishihara
66458a097e templater: require infix ++ operator to concatenate expressions
This eliminates ambiguous parsing between "func()" and "expr ()".

I chose "++" as template concatenation operator in case we want to add
bit-wise negate operator. It's also easier to find/replace than "~".
2023-03-01 16:39:23 +09:00
Yuya Nishihara
fd27d228ed templater: add concat(contents..) function, migrate default templates
Multi-line templates looked a bit ugly if I replaced all implicit concats
with ++ operations.
2023-03-01 16:39:23 +09:00
Yuya Nishihara
6bbf4c6fcf tests: extract log template function/variable for code readability
Also rewrites some lengthy templates. That's why the test output slightly
changed.
2023-03-01 16:39:23 +09:00
Ilya Grigoriev
00b18bcd18 templater: Upper and lowercase ids and strings 2023-02-21 22:50:27 -08:00
Yuya Nishihara
b44148871a templater: save alias chain to report type/name error in original context
Since type/name checking is made after alias substitution, we need to preserve
the original context to generate a readable error message.

We could instead attach a stack of (alias_id, span) to ExpressionNode, but
the extra AliasExpanded node helps to capture downstream error by a single
.map_err() call.
2023-02-14 10:06:28 +09:00
Yuya Nishihara
bfdaaa4257 templater: implement symbol/function alias expansion
Test vectors are mainly copied from revset.rs and adapted to the template
syntax.

Closes #1190
2023-02-14 10:06:28 +09:00
Yuya Nishihara
d0715a0935 cli: load [template-aliases] section and pass around aliases table 2023-02-14 10:06:28 +09:00
Martin von Zweigbergk
a67fbb6714 cli: switch default graph style to be Sapling's curved style
We seem to quite unanimously prefer this style, so let's make the
default.
2023-02-12 07:23:29 -08:00
Vamsi Avula
aacdcf629b author/committer templates: add a username method
I haven't used a proper email address parser as I'm not really sure if it's
worth the extra dependency and effort -- thoughts?
2023-02-11 15:38:27 +05:30
Yuya Nishihara
5bfecf112a templater: add parsing rule for integer literal, add i64 property
This will be used as a parameter of id.shortest*() methods. For now, only
decimal literal is supported, and there's no unary negate operator.
"0"-prefix is disallowed because it looks like an octal number.

I don't think we would want multiple integer types in the template language,
so I chose i64 as the integer type of reasonable width.
2023-02-05 17:21:54 +09:00
Yuya Nishihara
9a5a88238b templater: fix handling of method chaining of parenthesized expression 2023-02-05 17:21:54 +09:00
Yuya Nishihara
5342d2cfb7 templater: implement string.contains() method as example 2023-02-05 11:53:11 +09:00
Yuya Nishihara
a4be118981 templater: check number of method arguments 2023-02-05 11:53:11 +09:00
Yuya Nishihara
13b5661094 templater: add separate(sep, contents...) function
This is a copy of Mercurial's separate() function.
2023-02-04 15:19:02 +09:00
Yuya Nishihara
1883d62805 tests: extract helper that renders colored commit template 2023-02-04 15:19:02 +09:00
Yuya Nishihara
45a018ec6b templater: report invalid argument count as error
We'll probably need a helper to extract N..M arguments, but let's revisit
it later.
2023-02-03 12:06:04 +09:00
Yuya Nishihara
baf911459f templater: report invalid argument type as error 2023-02-03 12:06:04 +09:00
Yuya Nishihara
4eff802d87 templater: report keyword/function/method name error 2023-02-03 12:06:04 +09:00
Yuya Nishihara
7090fa0374 templater: report syntax error, don't panic()
Even though the template syntax is experimental, panicking parser makes
it difficult to write tests. So let's add minimal error handling. The error
types are basically copied from the revset module.

I made write_commit_summary() fall back to the default template if user
template had syntax error. It should be better than reporting parse error
after e.g. "jj abandon" finished successfully.
2023-02-03 12:06:04 +09:00
Yuya Nishihara
1911734acc templater: add wrapper that turns template back to string property
I have no idea whether or not any template expressions are intentionally
allowed as a label, but it makes sense to write something like
'label("phase-" phase, ...)' (if we had a phase keyword.) So I decided to
add .into_plain_text() instead of stricter .try_into_string().
2023-02-02 01:12:23 +09:00
Yuya Nishihara
e4cb1afd61 templater: fix crash on "".first_line() 2023-02-01 16:13:43 +09:00
Yuya Nishihara
259314b442 templater: reuse parse_commit_term() to coerce if() condition to bool
This should fix some inconsistent parsing of condition term.
2023-02-01 10:25:28 +09:00
Yuya Nishihara
195672f75e tests: extract helper that renders single commit template with no graph 2023-02-01 10:25:28 +09:00
Yuya Nishihara
a3d3947499 templater: move epsilon rule out of term rule
Suppose "template" is a sequence of "term"s, it makes more sense to handle
an empty sequence there. It might be even better to disallow empty template
other than the top-level one.
2023-01-29 08:54:14 +09:00
Yuya Nishihara
bf66beab36 templater: fix parsing of parenthesized expression
A "list" is a sequence of more than one "term" nodes, so it shouldn't contain
a single parenthesized node.

Also, a parenthesized "term" rule wasn't handled.
2023-01-29 08:54:14 +09:00
Ilya Grigoriev
65de7cb0eb jj log: Change conflicted branches from br? to br??
The divergent changes are marked with ?? (I found a single ? a bit easy to
overlook), and this should be consistent.

Ideally, the conflicted branches would also be red, but this takes a bit
larger changes to `templater.rs`: another `Property` as well as changes to
https://github.com/martinvonz/jj/blob/7f9a0a28/src/template_parser.rs#L385-L395
2023-01-09 22:44:45 -08:00
Yuya Nishihara
6f8fb09609 cli: append "\n" to commit description specified by -m/--message
Otherwise the description set by -m would differ from the one set by editor.
This fixes test_describe() which says "make no changes", but previously "\n"
would be added by the second "jj describe".

As you can see, almost all hashes change in CLI tests. This means in-flight
PRs will need to be rebased to update insta snapshots.

Description text could be normalized by CommitBuilder, but the caller would
have to normalize it beforehand to compare with the current description, so
we would need an explicit function anyway. Another idea is to add a newtype
that represents a normalized description, and make CommitBuilder require it.
Commit::description() will return &Description in place of &str to ensure
that commit.description() == raw_str wouldn't compile.

Git CLI provides --cleanup=<mode> option to switch normalization rules, but
I don't think we'll need such feature.
2022-12-22 14:59:03 +09:00
Martin von Zweigbergk
d8feed9be4 copyright: change from "Google LLC" to "The Jujutsu Authors"
Let's acknowledge everyone's contributions by replacing "Google LLC"
in the copyright header by "The Jujutsu Authors". If I understand
correctly, it won't have any legal effect, but maybe it still helps
reduce concerns from contributors (though I haven't heard any
concerns).

Google employees can read about Google's policy at
go/releasing/contributions#copyright.
2022-11-28 06:05:45 -10:00
Martin von Zweigbergk
759ddd1e60 git: on initial export, export all branches
As I said in the previous patch, I don't know why I made the initial
export to Git a no-op. Exporting everything makes more sense to
(current-)me. It will make it slightly easier to skip exporting
conflicted branches (#463). It also lets us remove a `jj export` call
from `test_templater.rs`.
2022-11-13 15:06:10 -08:00
Martin von Zweigbergk
6c600e98cf templater: indicate if branch needs to be pushed to a remote
It's useful to know when you've modified a branch that exists on a
remote. A typical case is when you have pushed a branch to a remote
and then rewritten it. This commit adds an indication in the
`branches` template keyword. A branch that needs to be pushed to a
remote now has a `*` at the end (similar to how conflicted branches
have a `?` at the end). Note that the indication only considers
remotes where the branch currently exists, so there won't be an
indication that the branch has not been pushed to a remote.

Closes #254
2022-11-09 22:44:55 -08:00