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

1464 commits

Author SHA1 Message Date
Yuya Nishihara
ce1f9ab9e5 cli: extract helper for revset benchmark
The benchmark ids slightly changed, but I think it's better to share the
target/criterion/revsets directory.
2023-03-30 19:13:11 +09:00
Martin von Zweigbergk
f7dbade07a cli: add a command for benchmarking many revsets
This command is similar to Mercurial's revset benchmarking command. It
lets you pass in a file containing revsets. I also included a file
with some revsets to test on the git.git repo. I put it in `testing/`,
which doesn't seem perfect. I'm happy to hear suggestions for better
places, or we can move it later if we find a better place.

Note that these tests don't clear caches between each run (or even
between tests), so revsets that rely on filtering commit data that's
not indexed appear faster than they typically are in reality.
2023-03-28 10:21:10 -07:00
Martin von Zweigbergk
7249be33b0 cli: replace jj bench walkrevs by generic jj bench revset
I suspect the `jj bench walkrevs` command was from before we had
support for revsets. Now there doesn't seem to be any reason to have a
specific command for only range revsets (`foo..bar`), so let's replace
it by a command for benchmarking an arbitrary revset.
2023-03-28 10:21:10 -07:00
Martin von Zweigbergk
327deeb0c4 cli: move jj bench commands to new module, hide behind feature flag
The `jj bench` commands are mostly meant for developers, so lets hide
the command from help and behind a `bench` feature flag. The feature
flags avoids bloating the binary with the `criterion` dependencies,
which was the reason I removed the command in 18c0b97d9d.
2023-03-28 10:21:10 -07:00
Martin von Zweigbergk
48fbf7e1bd cli: revive jj bench command
This just backs out commit 18c0b97d9d without making any changes,
except for resolving conflicts.

I want a way to benchmark different revsets on e.g. the Git Core repo
or the Linux repo.
2023-03-28 10:21:10 -07:00
Martin von Zweigbergk
bac2de6ac6 cli: add hint about testing with ssh -F /dev/null on SSH errors 2023-03-24 22:16:50 -07:00
Martin von Zweigbergk
6c28ec1608 cli: find working copy's first parent from commit store (not index)
This avoid another use of `IndexEntry`. The working-copy commit should
be in the cache here, so it shouldn't have any impact on performance.
2023-03-24 10:09:40 -07:00
Martin von Zweigbergk
a5b79f9b0e index: make topo_order() return commit ids instead of index entries
`IndexEntry` is specific to the default index store; we don't want it
in the interface.
2023-03-24 10:09:40 -07:00
Martin von Zweigbergk
75605e36af revset: iterate over commit ids instead of index entries
There are no remaining places where we iterate over a revset and need
the `IndexEntry`s, so we can now make `Revset::iter()` yield
`CommitId`s instead.
2023-03-23 21:58:15 -07:00
Yuya Nishihara
75d68fe24c templater: add "parents" keyword in place of "parent_commit_ids"
All commit keywords are mapped to nullary methods. No matter if we'll
introduce .field syntax and/or self. keyword, this implementation can be
reused.
2023-03-24 12:17:38 +09:00
Yuya Nishihara
f4235464c2 templater: extract function that builds commit keywords over property
New code inserts one more Commit::clone(), but I don't see a measurable cost
with "jj log -Tshow -r 'all()'".
2023-03-24 12:17:38 +09:00
Yuya Nishihara
90f27555e7 templater: remove repo reference from CommitOrChangeId
A repo reference is passed around by the language struct, so it's no longer
needed to embed in CommitOrChangeId.
2023-03-24 12:17:38 +09:00
Yuya Nishihara
9065b94dc1 templater: implement list methods for unformattable property 2023-03-24 12:17:38 +09:00
Yuya Nishihara
a0be6a5a11 templater: add support for unformattable property
A property of Commit type won't have a default format.
2023-03-24 12:17:38 +09:00
Yuya Nishihara
9d661d6f69 cli: render other kind of revset error suggestion as hint 2023-03-23 23:08:17 +09:00
Yuya Nishihara
ddeb645d7f cli: provide hint for typo of revset function name
This is similar to what Mercurial does. The similarity threshold is copied
from clap, but we might want to adjust it later.
2023-03-23 23:08:17 +09:00
Martin von Zweigbergk
9ed537b3e8 cli: leverage RevsetIteratorExt::commits() in jj log
I'm trying to remove uses of `IndexEntry`.
2023-03-23 04:50:33 -07:00
Yuya Nishihara
2a87e1f95a cli: call RevsetExpression::evaluate() directly if no symbol resolution needed
There should be no problem to evaluate revset against base_repo and collect
commit objects from (mut_)repo, but it seemed a bit odd.

In rebase examples other than the "new --insert-after", we could switch to
tx.repo(). However, I think the use of tx.base_repo() makes it clear that
there's no data dependency on the previous mutation.
2023-03-23 01:15:31 +09:00
Martin von Zweigbergk
5f74dd5db3 repo: implement Repo on ReadonlyRepo instead of its Arc
I'd like to be able to pass a `self` of `type `&ReadonlyRepo` to
functions that take a `&dyn Repo`. For that, we need `ReadonlyRepo`
itself to implement `Repo` instead of having `Arc<ReadonlyRepo>`
implement it. I could have solved it in a different way, but the `Arc`
requirement seems like an unnecessary constraint.
2023-03-21 21:43:44 -07:00
Martin von Zweigbergk
58e153af19 cli: use Transaction::repo() instead of base_repo() when possible
In most cases, we just need to access the commit backend and then the
shorter `base()` works. I noticed because I wanted to implement `Repo`
on `ReadonlyRepo` instead of on `Arc<ReadonlyRepo>` and then these
uses failed.
2023-03-21 21:43:44 -07:00
Martin von Zweigbergk
01d7239732 revset: make graph iterator yield commit ids (not index entries)
We only need `CommitId`s, and `IndexEntry` is specific to the default
index implementation.
2023-03-20 01:45:54 -07:00
Martin von Zweigbergk
2f876861ae graphlog: key by commit id (not index position)
The index position is specific to the default index implementation and
we don't want to use it in outside of there. This commit removes the
use of it as a key for nodes in the graphlog.

I timed it on the git.git repo using `jj log -r 'all()' -T commit_id`
(the worst case I can think of) and it slowed down from ~2.02 s to
~2.20 s (~9%).
2023-03-20 01:45:54 -07:00
Martin von Zweigbergk
fc84c02c8e cli: add jj describe --no-edit to not open editor 2023-03-19 00:48:05 -07:00
Martin von Zweigbergk
3bacc367cd cli: add jj describe --reset-author
I think requests to reset the author came up twice in the last week,
so let's just add support for it. I copied git's behavior of resetting
the name, email, and timestamp. The flag name is also from git.
2023-03-19 00:48:05 -07:00
Martin von Zweigbergk
2495c8f27e cargo: update MSRV to 1.64
We need 1.64 to bump `clap` to `4.1`. We don't really need to upgrade
to that, but being on an older version causes minor confusions like
#1393. Rust 1.64 is very close to 6 months old at this point.
2023-03-17 22:44:29 -07:00
Martin von Zweigbergk
70d4a0f42e revset: remove context parameter from evaluate()
The `RevsetWorkspaceContext` argument is now instead used by the new
`resolve_symbol()` function.
2023-03-17 22:42:41 -07:00
Martin von Zweigbergk
94aec90bee revset: resolve symbols earlier, before passing to revset engine
For large repos, it's useful to be able to use shorter change id and
commit id prefixes by resolving the prefix in a limited subset of the
repo (typically the same subset that you'd want to see in your default
log output). For very large repos, like Google's internal one, the
shortest unique prefix evaluated within the whole repo is practically
useless because it's long enough that the user would want to copy and
paste it anyway.

Mercurial supports this with its `revisions.disambiguatewithin` config
(added in https://www.mercurial-scm.org/repo/hg/rev/503f936489dd). I'd
like to add the same feature to jj. Mercurial's implementation works
by attempting to resolve the prefix in the whole repo and then, if the
prefix was ambiguous, it resolves it in the configured subset
instead. The advantage of doing it that way is that there's no extra
cost of resolving the revset defining the subset if the prefix was not
ambiguous within the whole repo. However, there are two important
reasons to do it differently in jj:

* We support very large repos using custom backends, and it's probably
  cheaper to resolve a prefix within the subset because it can all be
  cached on the client. Resolving the prefix within the whole repo
  requires a roundtrip to the server.

* We want to be able to resolve change id prefixes, which is always
  done in *some* revset. That revset is currently `all()`, i.e. all
  visible commits. Even on local disk, it's probably cheaper to
  resolve a small revset first and then resolve the prefix within that
  than it is to build up the index of all visible change ids.

We could achieve the goal by letting each revset engine respect the
configured subset, but since the solution proposed above makes sense
also for local-disk repos, I think it's better to do it outside of the
revset engine, so all revset engines can share the code.

This commit prepares for the new functionality by moving the symbol
resolution out of `Index::evaluate_revset()`.
2023-03-17 22:42:41 -07:00
Martin von Zweigbergk
ac23395ea1 cli: pass revset expression by value to evaluate_revset()
The callers don't need to hold on to the revset expression once it's
been evaluated, and having an owned expression (well, an expression
with shared ownership) will avoid a clone in the next commit.
2023-03-17 22:42:41 -07:00
Yuya Nishihara
998727266c templater: add join method to mapped template 2023-03-18 12:04:00 +09:00
Yuya Nishihara
2fbe581a71 templater: add trait that represents a mapped template
A mapped template is basically a combined function that takes context: &C,
extracts Vec<O>, and formats each item with Template<C>. It cannot be cleanly
turned into a function of (&C) -> Vec<Template<()>> type. So list-like methods
are implemented on Box<dyn ListTemplate<C>> instead.
2023-03-18 12:04:00 +09:00
Yuya Nishihara
ec5dd96e66 templater: convert template to Box<dyn Template> by caller
I'm going to add a trait that provides .join() -> Box<dyn Template>.
wrap_template() should handle it transparently, but the current interface
would require excessive boxing.
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
20a75947fe templater: add stub BuildContext object, pass it around build_() functions
A lambda parameter will be added there just like "locals" of expand_aliases().
2023-03-18 12:04:00 +09:00
Yuya Nishihara
369c119053 templater: generalize formattable list template for map operation 2023-03-18 12:04:00 +09:00
Yuya Nishihara
ea0cc374aa templater: extract low-level helper to format list items with separator
For map operation, we'll have to bind parameter and evaluate template for
each element, which can't be purely abstracted as a Template<()> type.
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
Martin von Zweigbergk
e2b4d7058d cli: move some debug commands to new (non-hidden) support group
The `jj debug` commands are hidden from help and are described as
"Low-level commands not intended for users", but e.g. `jj debug
completion` is intended for users, and should be visible in the help
output.
2023-03-17 06:50:55 -07:00
Martin von Zweigbergk
ce098a729a cli: remove jj hide as alias for jj abandon
I haven't heard of anyone using this alias, so let's remove it. It's
easy for users to add it as their own alias if they really want it.
2023-03-17 06:50:55 -07:00
Martin von Zweigbergk
fb7b680d1f cli: don't hide jj commit from help output
The command is not only useful for new users, it's also useful as a
combination of `jj describe` and `jj new`.
2023-03-17 06:50:55 -07:00
Martin von Zweigbergk
e64ca31bfd cli: show diff summary as two states instead of transition
By using one letter for the path type before and one letter for path
type after, we can encode much more information than just the current
'M'/'A'/'R'. In particular, we can indicate new and resolved
conflicts. The color still encodes the same information as before. The
output looks a bit weird after many years of using `hg status`. It's a
bit more similar to the `git status -s` format with one letter for the
index and one with the working copy. Will we get used to it and find
it useful?
2023-03-16 08:01:13 -07:00
Martin von Zweigbergk
ed1c2ea1aa cli: disallow jj diff --color-words --git 2023-03-16 08:01:13 -07:00
Martin von Zweigbergk
0899260f0c cli: try to clarify the help texts for jj op commands a little 2023-03-16 08:00:05 -07: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
Yuya Nishihara
b6a5d63b09 time_util: add functions to parse format spec and apply it later
In templater, it's easier to handle invalid format string at parsing stage, so
I want to build formatting items upfront. Since the formatting items borrow
the input string by reference, we need to manually convert them to the owned
variants.
2023-03-15 12:14:42 +09:00
Yuya Nishihara
731a94e4f2 time_util: cache parsed result of default time format
While measuring overhead of interpreter version of the template engine, I
noticed the templater spend some time in chrono. I don't think this would
matter in practice, but it's easy to cache the formatting items.

    % jj log -r'all()' -T'".\n"' --no-graph | wc -l
    2996

    % hyperfine --warmup 3 --runs 20 "jj log --ignore-working-copy -r 'all()' -Tshow --no-graph"
    (original)
      Time (mean ± σ):     120.0 ms ±  18.7 ms    [User: 97.5 ms, System: 22.5 ms]
      Range (min … max):    96.7 ms … 144.1 ms    20 runs
    (new)
      Time (mean ± σ):     106.2 ms ±  12.3 ms    [User: 86.1 ms, System: 20.1 ms]
      Range (min … max):    96.3 ms … 130.4 ms    20 runs

Regarding the template engine rewrites, I'm yet sure that the interpreter
version is strictly better. It's simpler, but could make some caching story
difficult. So I'm not gonna replace the engine anytime soon.
2023-03-15 12:14:42 +09:00
Martin von Zweigbergk
3871efd2f9 revset: move ReverseRevsetGraphIterator into revset module
The iterator is not specific to the implementation in
`revset_graph_iterator`, so it belongs in the standard `revset`
module.
2023-03-14 05:32:02 -07:00
Martin von Zweigbergk
f62fac24ac revset: move graph iteration onto Revset trait
We want to allow custom revset engines define their own graph
iterator. This commit helps with that by adding a
`Revset::iter_graph()` function that returns an abstract iterator.

The current `RevsetGraphIterator` can be configured to skip or include
transitive edges. It skips them by default and we don't expose option
in the CLI. I didn't bother including that functionality in the new
`iter_graph()` either. At least for now, it will be up to the
implementation whether it includes such edges (it would of course be
free to ignore the caller's request even if we added an option for it
in the API).
2023-03-14 05:32:02 -07: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
Martin von Zweigbergk
82101bc7e0 cli: let graphlog provide a default node symbol
I'm about to make the default (non-working-copy) node symbol be a
unicode symbol, but we only want that when using a unicode graph, so
users with a terminal that doesn't support unicode can get plain ASCII
output by setting e.g. `ui.graph.style = "ascii"`.
2023-03-12 23:21:05 -07:00
Martin von Zweigbergk
efc9cc9885 cli: avoid a call to Index::num_commits()
I'm trying to remove the function from the trait.
2023-03-12 22:08:31 -07:00
Martin von Zweigbergk
8c5c0f0e83 cli: make jj debug index get stats from specific implementation
We don't want custom index implementations to have to conform to the
same kind of stats as the default implementation. This commit also
makes the command error out on non-default index types.
2023-03-12 22:08:31 -07:00
Martin von Zweigbergk
504a2b3fd0 cli: add test of jj debug reindex, do full reindexing
I broke the commands in a27da7d8d5 and thought I just fixed it in
c7cf914694a8. However, as I added a test, I realized that I made it
only reindex the commits since the previous operation. I meant for the
command to do a full reindexing of th repo. This fixes that.
2023-03-12 22:08:31 -07:00
Yuya Nishihara
23bed2731c templater: extract evaluation interface and build_() functions to new module
I'm thinking of rewriting the evaluation part as a simple interpreter. It
will increase the runtime cost (about a few microseconds per entry I suppose),
but will greatly reduce the complexity of generic property function chaining.

The extracted template_builder module is the part I'm going to reimplement.
2023-03-13 11:45:17 +09:00
Yuya Nishihara
91d309a93c templater: extract little helper that parses text and expands aliases
The caller doesn't have to care about alias expansion.
2023-03-13 11:45:17 +09:00
Yuya Nishihara
b380ca0cf7 templater: move split_email() to text_util module
It's not specific to templating.
2023-03-13 11:45:17 +09:00
Martin von Zweigbergk
63b3c0899a index: make jj debug reindex actually reindex
I broke `jj debug reindex` in a27da7d8d5. From that commit, we no
longer delete the pointer to the old index, so nothing happens when we
reload the index. This commit fixes that, and also makes the command
error out if run on a repo with a non-default index type.
2023-03-12 03:23:59 -07:00
Martin von Zweigbergk
d2457d3f38 index: wrap ReadonlyIndex in new type, hiding Arc
Not all index implementations may want to store the readonly index
implementation in an Arc. Exposing the Arc in the interface is also
problematic because `Arc<IndexImpl>` cannot be cast to `Arc<dyn
Index>`.
2023-03-11 22:22:46 -08:00
Martin von Zweigbergk
e5ba9d9e42 index: move current implementation to default_index_store.rs
The idea is that `index.rs` contains the interface, similar to
`backend.rs` for commits, and `op_store.rs` for operations.
2023-03-11 22:22:46 -08:00
Yuya Nishihara
904e9c5520 cli: add ui.log-word-wrap option
Unlike Mercurial, this isn't a template keyword/function, but a config knob.
Exposing graph_width to templater wouldn't be easy, and I don't think it's
better to handle terminal wrapping in template.

I'm not sure if patch content should be wrapped, so this option only applies
to the template output for now.

Closes #1043
2023-03-11 12:01:17 +09:00
Yuya Nishihara
2a32d81542 graphlog: expose width() method to precompute graph width 2023-03-11 12:01:17 +09:00
Yuya Nishihara
6539381155 ui: allow to override terminal width with $COLUMNS variable
Writing text wrapping tests would be difficult without env/config overrides.
The logic is pretty much the same as ui.termwidth() of Mercurial.
2023-03-11 12:01:17 +09:00
Yuya Nishihara
afdf9e19f2 ui: simplify size() to only return width, rename it to term_width()
I'm going to add $COLUMNS override, and it should work even if ioctl() on tty
failed. This means that the return type has to be (Option<u16>, Option<u16>).
Since we don't use the row count, I decided to drop it.
2023-03-11 12:01:17 +09: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
ec554f6df2 cli: implement word wrapping function for labeled output 2023-03-10 16:07:55 +09:00
Yuya Nishihara
1c852b7fb9 cli: implement word wrapping function for bytes
wrap_bytes() is similar to textwrap::wrap(), but can process arbitrary bytes.
More importantly, it guarantees that byte offsets can be reconstructed from
the split slices. This allows us to interleave push/pop_label()s with split
text fragments.

We could calculate byte offsets upfront, but using slice API is more
convenient. That's why I didn't add inner function returning Vec<Range>.
2023-03-10 16:07:55 +09:00
Yuya Nishihara
c5046235b5 formatter: pass data range to replay callback instead of data slice
New word-wrap function will be implemented in two passes. The first pass
splits byte slice to lines, and the second pass inserts "\n" based on that
while interleaving push/pop_label() calls and text fragments. Since the second
pass combines multiple data sources, byte indices are more convenient than
slices there.
2023-03-10 16:07:55 +09:00
Yuya Nishihara
b41bdb548a templater: generalize IndentTemplate as reformatting template
New fill() function will also use this struct.
2023-03-10 16:07:55 +09:00
Yuya Nishihara
2af2aca7ff templater: extract indent function to text_util module
This prepares for adding generic template object for reformatting.
2023-03-10 16:07:55 +09:00
Yuya Nishihara
82604eda02 cli: extract complete_newline() to text_util module
I'll add more text formatting functions there.
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
f8f24399f2 templater: rename ListTemplate and "list" parsing node to "concat"
It's getting confusing since we now have a list property type.

expand/normalize_list() functions aren't renamed since they are also applied
to a list of function arguments.
2023-03-10 12:58:32 +09:00
Yuya Nishihara
aff5cd01d2 templater: while building, process template as a property variant
This is simpler, and it also unblocks the use of a Template<C> in method
return value position.
2023-03-10 12:58:32 +09:00
Yuya Nishihara
0f87649696 templater: add helper to create Expression with/without labels
These functions aren't suffixed with _property, since Expression::Template()
will be flattened into P::Template().
2023-03-10 12:58:32 +09:00
Yuya Nishihara
6af265a388 templater: move Box::new() wrapping to language.wrap_() functions
Now all callers do wrap_<type>(Box::new(...)), so its responsibility can be
moved to the callee without extra boxing.
2023-03-08 16:14:24 +09:00
Yuya Nishihara
96f4d8798c templater: remove redundant TemplateProperty wrapping from method chaining
TemplateFunction takes a property and a function to apply to the property
value. That's exactly what a method call does.
2023-03-08 16:14:24 +09:00
Martin von Zweigbergk
e509a299e5 cli: print commands in alphabetical order
Until https://github.com/clap-rs/clap/issues/1553 is fixed, I don't
think we can do better than alphabetical order (without a lot of
work).
2023-03-06 21:35:34 -08:00
Yuya Nishihara
4984e611f4 templater: add "parent_commit_ids" keyword
A list type isn't so useful without a map operation, but List<CommitId>
is at least printable. Maybe we can experiment with it to craft a map
operation.

If a map operation is introduced, this keyword might be replaced with
"parents.map(|commit| commit.commit_id)", where parents is of List<Commit>
type, and the .map() method will probably return List<Template>.
2023-03-07 11:33:15 +09:00
Yuya Nishihara
0b27f8371a templater: make Literal(str) or str usable as a template 2023-03-07 11:33:15 +09:00
Yuya Nishihara
7b206e6fb5 templater: add helper to format template properties with separator
contents will be an Iterator<Item = &P> where P is a Template<()>.
2023-03-07 11:33:15 +09:00
Samuel Tardieu
decca920c7 git push: do not consider @- if @ has non-empty content or description 2023-03-05 23:50:20 +01:00
Yuya Nishihara
5d184e6694 cli: in "show" template, indent description like Git does 2023-03-04 12:10:53 +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
558aa15e6e templater: remove Template::has_content() superseded by FormatRecorder 2023-03-04 12:10:53 +09:00
Yuya Nishihara
974a5145e0 templater: reimplement separate() by using buffered formatter
template.format(context, &mut recorder) wouldn't fail right now, but we
might add a runtime template error in future. So I added error handling there.
2023-03-04 12:10:53 +09:00
Yuya Nishihara
233d37f678 formatter: add buffer that records both data and push/pop_label() calls
Template functions like indent() or fill() need to manipulate labeled
output. Since indent() is line oriented, it could be implemented as a
post-processing filter. OTOH, fill()/wrap() inserts additional "\n"s. If we
do that as a post process, colorized text could be split into multiple lines,
and would mess up graph log output. By using FormatRecorder, we can apply
text formatting in between labels.

I thought we could disallow text wrapping of labeled template fragments, but
the example in #1043 suggests that we do want to wrap(whole_template_output)
rather than simple description.wrap().
2023-03-04 12:10:53 +09:00
Yuya Nishihara
39d3420694 templater: ignore all ascii whitespace characters
Per Rust/WhatWG definition.
https://doc.rust-lang.org/std/primitive.char.html#method.is_ascii_whitespace
2023-03-04 00:01:54 +09:00
Yuya Nishihara
224edd73ee templater: parse "\t" and "\r" as escape sequence 2023-03-04 00:01:54 +09:00
Yuya Nishihara
d9ed2895db templater: rewrite syntax tests to not build evaluation object
Now we have AST objects, so we don't need to evaluate integer literal to
test parsing results.
2023-03-04 00:01:54 +09:00
Vamsi Avula
33aad56464 template: allow tab as whitespace (along with the current space and newline)
My jjconfig is otherwise all indented with tabs and it helps for my
template-aliases to be indented the same way too.
2023-03-03 12:06:13 +05:30
Samuel Tardieu
5ecdeed606 git: only consider references matching globs when fetching 2023-03-02 10:09:08 +01:00
Samuel Tardieu
0ca4e2dad2 git: absence of globs is None rather than &[]
In `git_fetch()`, any glob present in `globs` is an "allow" mark. Using
`&[]` to represent an "allow-all" may be misleading, as it could
indicate that no branch (only the git HEAD) should be fetched.

By using an `Option<&[&str]>`, it is clearer that `None` means that
all branches are fetched.
2023-03-02 10:09:08 +01:00
Samuel Tardieu
6fd65cca30 git: use &[&str] instead of &[String]
Using &[String] forces the caller to materalize owned strings if they
have only references, which is costly. Using &[&str] makes it cheap
if the caller owns strings as well.
2023-03-02 10:09:08 +01:00
Yuya Nishihara
681944954e docs: document template syntax, keywords and methods
Not all keywords and methods have description, but I think the function
signature should help understand the behavior.
2023-03-02 15:31:19 +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
433623c138 cli: use separate(" ") to concatenate fields in default templates
Here we know each field will never be empty, but separate(" ", foo, bar)
looks slightly better than 'foo ++ " " ++ bar'. Implicit template concatenation
will be disabled soon.
2023-03-01 16:39:23 +09:00
David Barnett
99cb0ba7c5 Implement "config set" subcommand
Uses toml_edit to support simple config edits like:
  jj config set --repo user.email "somebody@example.com"
2023-02-28 18:18:02 -08:00
Martin von Zweigbergk
bbd6ef0c7b revset: remove filter_by_diff(), have caller intersect expression
To be able to make e.g. `jj log some/path` perform well on cloud-based
repos, a custom revset engine needs to be able to see the paths to
filter by. That way it is able pass those to a server-side index. This
commit helps with that by effectively converting `jj log -r foo
some/path` into `jj log -r 'foo & file(some/path)'`.
2023-02-28 17:45:34 -08:00
Yuya Nishihara
bab13e1982 cli: snapshot stale working copy before updating
Since there's no easy API to snapshot the stale working copy without releasing
the lock, we have to compare the tree ids after reacquiring the lock. We could
instead manually snapshot and rebase the working-copy commit, but that would
require more copy-paste codes.

Closes #1310
2023-02-28 12:59:30 +09:00
Yuya Nishihara
b7eb8ee438 cli: include command args in "snapshot working copy" op log
Since "import git refs" includes the args, there would be no point to exclude
snapshot_working_copy().
2023-02-28 12:59:30 +09:00
Martin von Zweigbergk
346e3c849b repo: propagate error when failing to look up backend type 2023-02-27 09:44:28 -08:00
Martin von Zweigbergk
011d9e3486 workspace: make WorkspaceLoader::load() return WorkspaceLoadError
I plan to make `RepoLoader::init()` return a `Result`, which means
that `WorkspaceLoader::load()` will need to return more kinds of
errors. Making it return `WorkspaceLoadError` is a good start. By also
extracting a function for converting `WorkspaceLoadError` to
`CommandError`, we can reuse a the handling of `PathError` in
`cli_util`.
2023-02-27 09:44:28 -08:00
Martin von Zweigbergk
ea6a238c7c cli: avoid creating new WorkspaceLoader for jj config edit --repo
This is mostly about not having to handle errors twice (or document an
`unwrap()` after `WorkspaceLoader::init()`).
2023-02-27 09:44:28 -08:00
Samuel Tardieu
c5e41a99c3 git remote rename: rename git refs as well 2023-02-26 15:22:18 +01:00
Samuel Tardieu
b515d14f18 git_fetch: when removing a remote branch, remove git ref as well 2023-02-26 15:22:18 +01:00
Yuya Nishihara
bfbb7d1399 cli: on finish_transaction(), print check-out summary by caller
This makes sense because the status is also printed by caller.
2023-02-23 14:15:38 +09:00
Yuya Nishihara
1cb473ab2a cli: on finish_transaction(), look up check-out commit by caller
So the caller can print a commit summary.

It's getting less clear why cli_util::update_working_copy() takes a repo
argument. It might be better to extract a helper struct that operates on
repo + workspace (minus CLI stuff), and move it to the lib crate.
2023-02-23 14:15:38 +09:00
Yuya Nishihara
3dd8b9a5f0 cli: extract update_working_copy() from finish_transaction()
I'll move some bits from the free update_working_copy() function to
deduplicate parse_commit_summary_template() call.
2023-02-23 14:15:38 +09:00
Yuya Nishihara
61d6604d3d cli: add workspace_command.get_wc_commit_id() for short
We can't replace all callers, but I think it's common enough to add a helper
function.
2023-02-23 14:15:38 +09:00
Ilya Grigoriev
49fd177c47 templater: Allow separate styling for change and commit ids 2023-02-21 22:50:27 -08:00
Ilya Grigoriev
00b18bcd18 templater: Upper and lowercase ids and strings 2023-02-21 22:50:27 -08:00
Ilya Grigoriev
643fe9a218 Remove no longer needed clippy bug workaround 2023-02-21 18:33:40 -08:00
Ilya Grigoriev
30d03a66e6 cmd: --branch option for git fetch.
Thanks to @samueltardieu for noticing a subtle bug in the refspecs, providing
the fix, as well as the two `conflicting_branches` tests.
2023-02-21 18:33:40 -08:00
Yuya Nishihara
4ec0bfb8f7 cli: rename op "head" color label to "current_operation"
FWIW, this change means a boolean "current_operation" keyword will be
highlighted even if it's false.
2023-02-21 00:24:58 +09:00
Yuya Nishihara
4f36367aee cli: rename "op-log" color label to "op_log"
Per discussion in #1289.
2023-02-21 00:24:58 +09:00
Yuya Nishihara
c2df989fe9 cli: add "op log -T" option and basic tests for template keywords 2023-02-20 18:20:41 +09:00
Yuya Nishihara
b5f1728ffb templater: migrate op log to template language
The outermost "op-log" label isn't moved to the default template. I think
it belongs to the command's formatter rather than the template.

Old bikeshedding items:
- "current_head", "is_head", or "is_head_op"
  => renamed to "current_operation"
- "templates.op-log" vs "templates.op_log" (the whole template is labeled
  as "op-log")
  => renamed to "op_log"
- "template-aliases.'format_operation_duration(time_range)'"
  => renamed to 'format_time_range(time_range)'
2023-02-20 18:20:41 +09:00
Yuya Nishihara
eafbd977a3 templater: add TimestampRange type, migrate operation time to it 2023-02-20 18:20:41 +09:00
Yuya Nishihara
da3c1d2286 templater: extract helpers to build expression of specific types 2023-02-20 18:20:41 +09:00
Yuya Nishihara
c2e0ebca12 templater: implement .into_template() helper on formattable property
So that I can blindly write property.into_template() to convert any property
type to template.
2023-02-20 18:20:41 +09:00
Yuya Nishihara
854a3e64fa templater: split IntoTemplate trait
The next commit will implement .into_template() on Box<dyn TemplateProperty>,
so I want a trait for this particular method.
2023-02-20 18:20:41 +09:00
Ilya Grigoriev
9c51d74b2c cmd: Allow multiple -b for jj rebase
This also makes `rebase_branch` reuse `rebase_descendants`.

This addresses a portion of #1158
2023-02-20 00:36:32 -08:00
Ilya Grigoriev
f04458a245 cmd: Allow multiple -s for jj rebase
This addresses a portion of #1158

One application (not the prettiest, but useful until we have `jj sync`):

    jj rebase -s oldmain+~:main -d main -L
2023-02-20 00:36:32 -08:00
Ilya Grigoriev
53476a77f7 cmd: Make jj restore work if @ is a merge commit
To be clear, this applies to `jj restore` without any arguments.

Fixes #1228
2023-02-19 22:55:53 -08:00
Martin von Zweigbergk
bc9f66dad3 revset: replace RevsetIterator wrapper by extension
The type doesn't seem to provide any benefit. I don't think I had a
good reason for creating it in the first place; it was probably just
unfamiliarity with Rust.
2023-02-19 21:37:26 -08:00
Martin von Zweigbergk
30160f4d20 revset: pass revset, not iterator, into RevsetGraphIterator
I was thinking of replacing `RevsetIterator` by a regular
`Iterator<Item=IndexEntry>`. However, that would make it easier to
pass in an iterator that produces revisions in a non-topological order
into `RevsetGraphIterator`, which would produce unexpected results (it
would result in nodes that are not connected to their parents, if
their parents had already been emitted). I think it makes sense to
instead pass in a revset into `RevsetGraphIterator`.

Incidentally, it will also be useful to have the full revset available
in `RevsetGraphIterator` if we rewrite the algorithm to be more
similar to Mercurial's and Sapling's algorithm, which involves asking
the revset if it contains parent revisions.
2023-02-19 21:37:26 -08:00
Yuya Nishihara
a3efb74cfc commit_templater: make commit/change_id typed again
This basically undoes d6c6cdb45c "templater: store type-erased version of
commit/change id." Since they are looked up differently, they should preserve
the original types.
2023-02-20 13:41:44 +09:00
Samuel Tardieu
863a6e6d09 git push: add --deleted option 2023-02-19 18:18:53 +01:00
Yuya Nishihara
4f9e75c7d1 templater: use macro to implement property kind wrappers 2023-02-19 16:18:39 +09:00
Yuya Nishihara
aaae90a599 commit_templater: turn property structs into functions 2023-02-19 16:18:39 +09:00
Yuya Nishihara
cf1b609de2 commit_templater: rename 'repo lifetime for clarity
FWIW, I'm thinking of making the repo parameter generic over Arc<ReadonlyRepo>
and &MutableRepo. It will allow us cache a parsed commit_summary template.
2023-02-19 16:18:39 +09:00
Yuya Nishihara
c5ddd14c13 commit_templater: extract runtime objects from templater.rs
This should reduce future merge conflicts around use statements.
2023-02-19 16:18:39 +09:00
Yuya Nishihara
c396b4cecf commit_templater: extract parsing functions from template_parser.rs
parse_commit_template() is renamed to commit_templater::parse().
2023-02-19 16:18:39 +09:00
Yuya Nishihara
73b7954060 templater: make common parser types and utility functions public
So the commit templater can be extracted to new module.
2023-02-19 16:18:39 +09:00
Yuya Nishihara
a28396fc86 templater: extract "commit" property variants to separate enum
Now it's ready to split template_parser/templater into base template functions
and "commit" templater. I think Signature and Timestamp are basic types, so
they aren't moved to CommitTemplatePropertyKind. Perhaps, a duration type from
OpTemplate will also be added to CoreTemplatePropertyKind.
2023-02-19 11:31:22 +09:00
Yuya Nishihara
7ee2ff862f templater: rename Property enum to CoreTemplatePropertyKind
I'll add CommitTemplatePropertyKind.
2023-02-19 11:31:22 +09:00
Yuya Nishihara
5474268d22 templater: parameterize property type 2023-02-19 11:31:22 +09:00
Yuya Nishihara
907bddaf1e templater: add conversion trait for common template types
Maybe we can split traits per type (such as IntoTemplate), but a single
trait should be good enough to abstract "Property" enums.
2023-02-19 11:31:22 +09:00
Yuya Nishihara
2be34ab552 templater: proxy Property::<variant>() wrapping through language trait
The idea is that a derived language will do wrap_<core_type>() as
DerivedProperty::Core(CoreProperty::<Type>(property)). This could be dealt
with some From<CoreProperty> trait impls, but the resulting code looked
a mess, and compile errors would be cryptic. I think this is somewhat similar
to serde::Serializer API.

I also rejected the idea of abstracting property types over Box<dyn>. Maybe
it's okay for method dispatching and extraction of some basic types, but it
wouldn't work if we want to implement comparison operators for any compatible
types.

wrap_commit_or_change_id() and wrap_shortest_id_prefix() will be moved to
the CommitTemplateLanguage. I'll add impl_wrap_fns() macro after splitting
the modules.
2023-02-19 11:31:22 +09:00
Yuya Nishihara
52df6f2e81 templater: proxy build_core_method() through language trait
The "core" template parser wouldn't know how to dispatch property of types
added by a derived language. For example, CommitOrChangeId/ShortestIdPrefix
will be moved to the "commit" templater.
2023-02-19 11:31:22 +09:00
Yuya Nishihara
3361130df4 templater: introduce trait that abstracts property kind and keywords
This trait will provide ways to dispatch keyword/method nodes, and wrap
TemplateProperty object with a dedicated "Property" enum.

build_keyword() and context parameter "I"/"C" have been migrated to it.
2023-02-19 11:31:22 +09:00
Yuya Nishihara
4b00fb70d0 templater: extract function that dispatches method call by property type
A derived template language (e.g. commit template) will forward method calls
of the core types to this function.
2023-02-18 01:16:43 +09:00
Yuya Nishihara
7784768dc6 templater: inline PropertyAndLabels into Expression::Property()
It's no longer used at type position.
2023-02-18 01:16:43 +09:00
Yuya Nishihara
84ad048f24 templater: move initial labeling out of keyword function
I'm going to extract functions specific to commit templates, and auto labeling
feature should be a part of the core template language.
2023-02-18 01:16:43 +09:00
Ilya Grigoriev
e4aa2cb2e5 Rename ui.relative-timestamps to ui.oplog-relative-timestamps 2023-02-15 21:26:14 -08:00
Ilya Grigoriev
859b0f680c Make ui.relative-timestamps default to true
This seems like a better default for `jj op log`, which is now the only thing
this option affects.
2023-02-15 21:26:14 -08:00
Martin von Zweigbergk
d8997999f2 repo: replace RepoRef by Repo trait 2023-02-15 19:15:17 -08:00