Commit graph

1038 commits

Author SHA1 Message Date
Evan Mesterhazy
c3ee86d92a Split rebase_descendants into two functions
This refactor will allow us to reuse new `rebase_descendants` function for the
`jj split --siblings` feature (#2274) and later possibly for `jj parallelize`
(#1079).
2024-04-01 19:22:47 -04:00
Martin von Zweigbergk
7b3f8e8cb6 resolve: remove --quiet flag, rely on global one 2024-04-01 13:00:27 -07:00
Martin von Zweigbergk
adf3b50209 cli: add a global --quiet flag, which silences status messages
Note that `jj resolve` already had its own `--quiet` flag. The output
with `--quiet` for that command got a lot quieter with the global
`--quiet` also taking effect. That seems reasonable to me.
2024-04-01 13:00:27 -07:00
Martin von Zweigbergk
4962d9af3b ui: make hint_*() methods return Option
Same reasoning as the previous patch: we can avoid doing work when
`--quiet` is passed.
2024-04-01 13:00:27 -07:00
Martin von Zweigbergk
e38e2904bb ui: make status() return a dyn Write, add status_formatter()
When the caller needs a formatter, it's because they're doing
something non-trivial. When the user passed `--quiet` (see upcoming
patch), we should ideally skip doing related work for print the
formatting output. It helps if the `Ui` object doesn't even return a
`Formatter` then, so the caller is forced to handle the quiet case
differently.

Thanks to Yuya for the suggestion.
2024-04-01 13:00:27 -07:00
Martin von Zweigbergk
b940f1a092 errors: don't use the ui.hint*() helpers
I'm about to make hints not get printed with `--quiet`, but error
hints are probably still useful to get. They shouldn't be a problem
for scripts since the script would have to deal with the error anyway.
2024-04-01 13:00:27 -07:00
Martin von Zweigbergk
aeaab8aad3 cli: add a Ui::status() helper for writing non-error to stderr
This clarifies that status messages are not errors, and allows us to
implement a global `--quiet` flag for silencing status messages.
2024-04-01 13:00:27 -07:00
Simon Wollwage
320f50e00f cli: rename --all to --all-remotes for branch list 2024-04-01 10:12:13 +09:00
Yuya Nishihara
6004efb3b2 cli: replace last use of evaluate_revset() with evaluate_programmatic()
evaluate_programmatic() should be allowed here. AFAIK, the contract is that
the expression should never contain any bare symbols and "fallible" symbol-like
expressions, which doesn't apply to branches() and remote_branches() functions.

evaluate_revset() is removed because there are no callers. However, it's simple
and basic function, so we might want to reintroduce it if needed.
2024-04-01 10:08:44 +09:00
Yuya Nishihara
b3d3b26656 cli: make check_rewritable() not evaluate revset to commit objects 2024-04-01 10:08:44 +09:00
Yuya Nishihara
784d735ecc cli: add convenient method to intersect user revset with other expression
This pattern is common, and most callers of evaluate_revset() can now be
migrated to the wrapper API.
2024-04-01 10:08:44 +09:00
Yuya Nishihara
690270670e cli: add convenient wrapper for user revset evaluation
Many callers of resolve_revset() and evaluate_revset() will be migrated to
this wrapper. "single" and "default_single" APIs won't be replaced because
they require more contexts to construct error messages.

id_prefix_context() now uses bare revset::parse() to avoid dependency cycle.
2024-04-01 10:08:44 +09:00
Evan Mesterhazy
75e938c6b8 Fix the description of the --source arg in the jj rebase --help docs 2024-03-31 16:42:38 -04:00
Simon Wollwage
8eed08b8b6 cli: allow branch list to combine -r and -a 2024-03-31 23:37:22 +09:00
Yuya Nishihara
a6615bf36d cli: render string pattern suggestion as a hint
Templater doesn't have the one yet, but I think it belongs to the same
category.

For clap::Error, we could use clap's own mechanism to render suggestions as
"tip: ...", but I feel "Hint: ..." looks better because our error/hint message
is capitalized.
2024-03-30 23:53:17 +09:00
Yuya Nishihara
d759ba11f1 revset: don't stringify StringPatternParseError
This helps to add hint at the CLI layer.
2024-03-30 23:53:17 +09:00
Yuya Nishihara
339b199ee3 templater: merge ParseIntError into generic Expression error
It was only needed to attach the source error object, which is now handled
by the outer error type.
2024-03-30 23:53:17 +09:00
Yuya Nishihara
76f3b80e8a templater: consolidate "unexpected expression" error constructors
I also renamed "UnexpectedExpression" to just "Expression" because "unexpected"
doesn't apply to "immutable" revset parse/evaluation errors.
2024-03-30 23:53:17 +09:00
Yuya Nishihara
b09732f4f8 revset, templater: split parse error constructor that sets source error object
I'm going to add RevsetParseError constructor for InvalidFunctionArguments,
with/without a source error, and I don't want to duplicate code for all
combinations. The templater change is just for consistency.

I couldn't find a good naming convention for the builder-like API, so it's
called .with_source(mut self, _). Another option was .source_set(source).
Apparently, it's not uncommon to name consuming constructor as
with_<something>().
2024-03-30 23:53:17 +09:00
Yuya Nishihara
db15571eca cli: simplify check for non-empty revisions with/without "all:"
If "all:" is specified, an empty set should be allowed within that expression.
So the additional check we need here is to ensure that the resulting set is not
empty.
2024-03-30 22:40:05 +09:00
Yuya Nishihara
05242c95cd cli: don't silently omit root parent by "jj new --insert-before"
Spotted by Benjamin Tan.
2024-03-30 22:40:05 +09:00
Yuya Nishihara
73b60903ce tree: flatten TreeMergeError into BackendError 2024-03-30 22:40:05 +09:00
Yuya Nishihara
08b5b66ad4 cli: let backend decide whether merge with root can be performed
One less CLI revset helper. It might look odd that "jj rebase" says "Merge
failed" whereas "jj new" doesn't, but that depends on where the BackendError
is detected.
2024-03-30 11:14:25 +09:00
Yuya Nishihara
f20004fffe git_backend: classify "merge with root" as user error
Perhaps, there will be more error types that hold BackendError internally, but
this change is good enough to handle a merge error.
2024-03-30 11:14:25 +09:00
Yuya Nishihara
91ff1fdd1e cli: extract CommandError::with_message() constructor 2024-03-30 11:14:25 +09:00
Yuya Nishihara
1e83faf4f8 tree: remove useless "Backend error" message from TreeMergeError
I don't think it adds any contextual information. TreeMergeError is somewhat
similar to BackendError.
2024-03-30 11:14:25 +09:00
Evan Mesterhazy
dd1def02e4 Move parse_string_pattern in cli to StringPattern::parse in lib
This commit moves the parse_string_pattern helper function into the
str_util module in jj lib and adds tests for it.

I'd like to reuse this code in a function defined by `UserSettings`, which is
part of the jj lib crate and cannot use functions from the cli crate.
2024-03-29 08:48:09 -04:00
Yuya Nishihara
f83d1a840e templater: don't panic on PropertyPlaceholder unset error
The idea is that, if .extract() succeeded in static context, it means the
property can be evaluated as constant. This will potentially eliminate
expect_string_literal_with(), though I'm not too sure if it's a good idea.
If needed, maybe we can extend the idea to suppress type/name resolution errors
by "if(some_static_config_knob, x, y)".
2024-03-29 19:15:02 +09:00
Yuya Nishihara
32b623db67 templater: propagate error from formatted string property 2024-03-29 19:15:02 +09:00
Yuya Nishihara
71c2006c9b templater: introduce Formatter wrapper to switch strict/lax evaluations
This allows us to propagate property evaluation error to a string property. For
instance, "s.contains(x ++ y)" will be an error if "y" failed to evaluate,
whereas bare "x ++ y" shouldn't.

The other implementation ideas:

 a. add Template::into_string_property() to enable strict evaluation
    => it's tedious to implement it for each printable type
 b. pass (formatter, error_handler) arguments separately
    => works, but most implementors don't need error_handler argument
 c. pass strict=bool flag around build_*() functions
    => didn't tried, but it would be more complicated than this patch

Because Template trait is now implementation detail of the templater, it
should be okay to use a non-standard formatter wrapper.
2024-03-29 19:15:02 +09:00
Benjamin Tan
e7edafc924 rebase: do not modify commit IDs if commit is unchanged after rebase 2024-03-29 15:22:50 +08:00
Yuya Nishihara
dcf75788e0 sparse: extract "set --reset" to subcommand
Since --reset conflicts with the other flags, "set --reset" seems odd.
2024-03-29 11:02:31 +09:00
Yuya Nishihara
db94848341 sparse: deduplicate edited patterns
Since "set --add" removes duplicated patterns, it makes sense for "edit" to do
the same thing.
2024-03-29 11:02:31 +09:00
Yuya Nishihara
28e4331787 sparse: extract "set --edit" to subcommand
Even though --edit can be combined with --add/--remove/--clear/--reset, I don't
think it's practically useful.
2024-03-29 11:02:31 +09:00
Yuya Nishihara
0711ac30c3 sparse: extract helper that updates sparse patterns within workspace lock
I assumed locked_wc.sparse_patterns() is cheap operation. If it isn't, a
locked_ws/wc should be passed to the callback instead.
2024-03-29 11:02:31 +09:00
Yuya Nishihara
fff852f136 sparse: parse and print patterns as workspace-relative paths
Per comment in
https://github.com/martinvonz/jj/pull/3379#pullrequestreview-1963841604

Though cwd-relative path might be useful for --remove, I don't think that's
the common use case. The new behavior is consistent with --edit.
2024-03-29 11:02:31 +09:00
Austin Seipp
2d0b6560e8 cli: allow multiple -r options for duplicate/abandon
Commands like `new`, `duplicate`, and `abandon` can take multiple revset
arguments which results in their collective union. They take the revisions
directly as arguments. But for consistency with many other commands, they can
also take the `-r` argument, which is a no-op. However, due to the flag being
specified as a `bool`, the `-r` option can only be specified once, so e.g.
`abandon -r x -r y` often fails. I normally use `-r` for consistency and muscle
memory, so this bites me often.

Instead, use `clap::ArgAction::Count` in order to allow `-r` to be specified
multiple times. It remains unused, of course.

With this change, all the following invocations are equivalent. Before this
change, the second example would fail due to  giving `-r` multiple times.

    jj abandon x y
    jj abandon -r x -r y
    jj abandon -r 'x | y'

Note: `jj new` already supported this exact case actually, but it used an
awkward trick where it used `.overrides_with()` in order to override *itself* so
it could be specified multiple times. I believe this is a bit clearer.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
Change-Id: Ib36cf81d46dae4f698f06d0a32e8fd3120bfb4a4
2024-03-28 15:29:47 -05:00
Yuya Nishihara
916dc30828 revset: use common argument error instead of FsPathParseError
It's not special compared to the other argument errors, and we can now track
the error source separately.
2024-03-28 10:53:06 +09:00
Yuya Nishihara
074e6e12bc revset, templater: include short parse error description in summary line
This makes the summary line more informative. Even though it just duplicates
the message printed later, I think it's easier to follow.

This patch also adjusts some RevsetParseError messages because it seemed
redundant to repeat "revset function", "argument", etc.
2024-03-28 10:53:06 +09:00
Yuya Nishihara
d17166628f revset, templater: simplify parse error impls by using thiserror
This patch moves all "source" errors to the source field to conform to
thiserror API. It will probably help to keep ErrorKind enums comparable.
2024-03-28 10:53:06 +09:00
Yuya Nishihara
2cd70bdf14 revset, templater: render parse error as usual error chain
Because the CLI error handler now prints error sources in multi-line format,
it doesn't make much sense to render Revset/TemplateParseError differently.

This patch also fixes the source() of the SyntaxError kind. It should be
self.pest_error.source() (= None), not self.pest_error.
2024-03-28 10:53:06 +09:00
Yuya Nishihara
844d3d0ff0 revset, templater: allow any kind of error as parse error source
I'm going to make TemplateParseError hold RevsetParseError as Box<dyn _>, but
Box<dyn std::error::Error ..> doesn't implement Eq. I could remove Eq from
ErrorKind enums, but it's handly if these enums remain as value types.

This change will also simplify fmt::Display and error::Error impls.
2024-03-28 10:53:06 +09:00
Yuya Nishihara
790b5846f6 sparse: don't use io::Error to report invalid path stored in repository
I think it's more like data corruption, which is usually reported as an
internal error.
2024-03-28 10:52:51 +09:00
Yuya Nishihara
5c22164a26 sparse: make "sparse set --edit" accept only workspace-relative paths
I don't think it needs to convert absolute file paths to workspace paths.
2024-03-28 10:52:51 +09:00
Yuya Nishihara
a2a9b7decb templater: add coalesce() function that selects first non-empty content
This can be used to flatten nested "if()"s. It's not exactly the same as "case"
or "switch" expression, but works reasonably well in template. It's not uncommon
to show placeholder text in place of an empty content, and a nullish value
(e.g. empty string, list, option) is usually rendered as an empty text.
2024-03-28 10:51:47 +09:00
Yuya Nishihara
423a2a5446 cli: colorize commits summary embedded in single revset resolution hint
I think a colorized commit summary is easier to follow.
2024-03-27 09:06:06 +09:00
Yuya Nishihara
1061c91bde cli: add support for formatted error hints
A formatted error is not a string containing ANSI escape sequences because 1.
the output may be differently colored inside "hint", 2. the caller might not
be accessible to ui.new_formatter().
2024-03-27 09:06:06 +09:00
Yuya Nishihara
a25cac70b7 cli: highlight error source headers as well
Highlighting "{n}: " will help to follow error sources containing multi-line
messages. I'm going to make revset/template alias errors be formatted as plain
error chain.
2024-03-27 00:15:50 +09:00
Yuya Nishihara
195e788f92 cli: colorize only "Error: "/"Warning: "/"Hint: " headings
I think long message is easier to read if printed in the default color. Errors
and warnings are printed in bold to make them distinct.
2024-03-26 11:23:13 +09:00
Yuya Nishihara
078acc9eee cli: print "Failed to wait on pager" as warning
Since it doesn't terminate jj, it can be considered a warning.
2024-03-26 11:23:13 +09:00
Yuya Nishihara
31525705db cli: add "Hint: " or "Warning: " heading to almost all messages
It's inconsistent that some warnings have headings and some don't, and it seems
the choice is arbitrary. Let's unify the style. There are two exceptions:
1. continued line following labeled message,
2. "unrecognized response" followed by prompt.
2024-03-26 11:23:13 +09:00
Yuya Nishihara
6a98799176 tests: use jj_cmd_ok() in test_git_fetch_single_remote() 2024-03-26 11:23:13 +09:00
Yuya Nishihara
b363e695e4 commit_templater: make git_head return Option<RefName> instead of Vec<_>
Since we've introduced Option type, it no longer makes sense that git_head
returns a Vec<RefName>.
2024-03-26 00:28:43 +09:00
Yuya Nishihara
bd3d9309ff cli: add convenient methods to print hint or warning with default headings
The lowercase "warning: " is unified to "Warning: " as it is the jj's
convention afaik.

The _default() suffix could be dropped from these methods, but it's probably
better to break the existing codebase for the moment. Otherwise, the caller
might do writeln!(ui.warning(), "Warning: ..").
2024-03-26 00:28:27 +09:00
Yuya Nishihara
2e91146d67 cli: highlight "Error: " headings 2024-03-26 00:28:27 +09:00
Yuya Nishihara
1ebe751c42 cli: highlight "Warning: " and "warning: " headings 2024-03-26 00:28:27 +09:00
Yuya Nishihara
78ce9eae65 cli: highlight "Hint: " heading
The existing .hint() method is renamed to .hint_no_heading() to clarify that
it's not the default choice to print a hint. I'll add .hint_default() later,
which will be the shorthand for .hint_with_heading("Hint: ").
2024-03-26 00:28:27 +09:00
Yuya Nishihara
894219dd77 formatter: add wrapper that writes labeled heading once with content
This will be used to label "Error: " heading and content differently. I want
to see an error message in the default (white) color because it's easier to
read, but I still want to highlight the "Error: " heading.

We can achieve that without introducing new wrapper, but the resulting code
would look something like "writeln!(ui.error("Error: ")?, ..)?", and it would
get messier if the caller had to suppress io::Error.
2024-03-26 00:28:27 +09:00
Martin von Zweigbergk
d2043f069e repo: delete record_rewritten_commit()
I don't think we have any callers left that call
`record_rewritten_commit()` multiple times within a transaction and
expect it to result in divergence. I think we should consider it a bug
to do that.
2024-03-25 06:53:14 -07:00
Martin von Zweigbergk
e55168fa3e repo: make record_rewritten_commit() accept only one replacement id
All callers now pass a single new commit and I would like to keep it
that way.
2024-03-25 06:53:14 -07:00
Yuya Nishihara
02d4d14211 next, prev: fix choice from more than two targets 2024-03-25 20:51:54 +09:00
Yuya Nishihara
15ff7dfd48 cli: indent commits summary in single revset resolution hint
This is the same formatting as "jj abandon" output. It should improve the
discoverability of the trailing hint.
2024-03-25 11:15:28 +09:00
Yuya Nishihara
65ef700f94 cli: format single revset resolution hint with reused template instance
I'm going to introduce two changes: 1. indent commit summary, 2. colorize
output. The former can be implemented without using the templater API, but the
latter can't.
2024-03-25 11:15:28 +09:00
Yuya Nishihara
96e0bc0bdd templater: turn logical && and || into short-circuiting operators
Since the context (or self) property is no longer passed by argument, it's easy
to implement short-circuiting behavior.
2024-03-25 11:15:18 +09:00
Yuya Nishihara
df7be43ab6 templater: update comment why Template isn't TemplateProperty<Output = ..>
They are similar in a way that both of them can represent dynamic/static
evaluation, but their behaviors are different in error handling.
2024-03-25 11:15:09 +09:00
Yuya Nishihara
577e030db2 templater: remove unused context parameter from Template<C>
IntoTemplate will be cleaned up later. Perhaps, the lifetime parameter can be
removed at this point, but I'm planning to remove the IntoTemplate trait at all.
2024-03-25 11:15:09 +09:00
Yuya Nishihara
24ab8f7011 templater: turn Root/PlaceholderTemplate into non-Template type
The type parameter 'C' will be removed from the Template trait, making it
represent a printable type or compiled template.

TemplateRenderer now holds Box<dyn _> template because it's unlikely that the
inner template type can be statically determined.
2024-03-25 11:15:09 +09:00
Yuya Nishihara
f312307cbf git-push: process --change branches first to avoid pushing old branch state
This fixes --change/--branch conflicts by making --change precede --branch. I
don't think this is the most obvious behavior, but it's the easiest workaround.
2024-03-24 16:20:26 +09:00
Yuya Nishihara
538bfbc8a4 git-push: filter out duplicated branch names by caller
This is the common pattern among other classify() loops. I also changed the
set to hold &str as it doesn't need owned strings.
2024-03-24 16:20:26 +09:00
Yuya Nishihara
d749ef0195 git-push: extract function that updates push-{change_id} branches 2024-03-24 16:20:26 +09:00
Yuya Nishihara
620f0cd35f git-push: check duplicated --change branch prior to recording branch_updates
It could be moved before set_local_branch_target() to not update the local
branch, but it seemed weird that --change is silently ignored. This
inconsistency will be addressed later.
2024-03-24 16:20:26 +09:00
Yuya Nishihara
f88679bb45 tests: run "git push" with both --change and --branch arguments
It's unclear whether --change should precede or not, but it's wrong to try to
push the same branch twice.
2024-03-24 16:20:26 +09:00
Yuya Nishihara
e50d96e01d cli: split single revset resolution hint to paragraphs
Perhaps, this makes it slightly easier to spot the last "Hint:" line. We can
also render "Error:" and "Hint:" prefixes in different color/style.
2024-03-24 10:45:52 +09:00
Yuya Nishihara
b77a110e8a cli: remove less-frequently-used user_error factories 2024-03-24 10:45:52 +09:00
Yuya Nishihara
2523dc188c cli: allow to attach multiple hints to CommandError
Even though the number of the hints is usually 0 or 1, this simplifies the
API and hints handling.
2024-03-24 10:45:52 +09:00
Yuya Nishihara
bb0dcc059c cli: extract helper that prints error message, sources, and hint 2024-03-24 10:45:52 +09:00
Yuya Nishihara
aeb3470b5d cli: reorganize CommandError as (kind, err, hint) tuple
This helps to implement CommandError::add_hint(). The inner errors could be
embedded in the enum as before, but they're mostly of the same type. And I think
it's okay to use downcast_ref() to deal with the clap::Error special case.
2024-03-24 10:45:52 +09:00
Yuya Nishihara
7a2077a434 cli: extract clap::Error handling to function 2024-03-24 10:45:52 +09:00
Yuya Nishihara
c333481496 cli: add more CommandError factory functions, consolidate inner type
I'm going to reorganize CommandError as (kind, err, hints) tuple so that we
can add_hint() to the constructed error object.

Some config error messages are slightly adjusted because the inner error is
now printed in separate line.
2024-03-24 10:45:52 +09:00
Yuya Nishihara
c311131ee2 log: encode elided node as None
Since elided graph entry has no associated commits, it makes some sense to
represent as None?
2024-03-24 10:32:15 +09:00
Yuya Nishihara
2fc7febaef commit_templater: teach elidable (or optional) commit
I think Option<Commit> is the simplest encoding of the log node.

The behavior of an Option type is closer to nullable types rather than the
Option in Rust. I don't think we would want to write opt.map(|x| x.f()) or
opt.unwrap().f(). We can of course add opt?.f() syntax, but it will be a short
for "if(opt, opt.f())"?
2024-03-24 10:32:15 +09:00
Simon Wollwage
63771d6e84 cli: add option to list only conflicted branches
As requested in #1471, I added a new flag for `jj branch list` to only show branches that are conflicted.

Adds a unit test to check for listing only conflicted branches and regenerates the cli output to incorporate the new flag.

Closes #1471

reformat
2024-03-23 22:04:14 +09:00
Benjamin Tan
3034dbba3f git-push: Display messages from remote
The implementation of sideband progress message printing is aligned with
Git's implementation. See
43072b4ca1/sideband.c (L178).

Closes #3236.
2024-03-23 20:17:04 +08:00
Benjamin Tan
2831459a95 ui: Remove &mut requirement for prompt functions 2024-03-23 20:17:04 +08:00
Yuya Nishihara
fad712811c templater: leverage TemplateProperty::map/and_then() helpers 2024-03-23 16:22:17 +09:00
Yuya Nishihara
a3d44485f4 templater: add helper methods to map property like Option/Result
These two are common when implementing methods. Fortunately, the
"return-position impl Trait in traits" feature is stabilized in Rust 1.75.0,
so we don't need another variant of TemplateFunction.
2024-03-23 16:22:17 +09:00
Ilya Grigoriev
02a04d0d37 test_conflicts and test_resolve_command: use indoc! to indent conflict markers in tests
Apart from (IMO) looking nicer, this will also sidestep the potential problem
that if the file contains actual jj conflict markers (`>>>>>>>` in the beginning
of a line, for example), jj would currently have trouble materializing and
subsequently parsing conflicts in the file if it actually became conflicted.

I'll demo this bug in either this or a subsequent PR. It's the kind of bug that
sounds serious in theory but might never cause a problem in practice.

After this PR, only `docs/tutorial.md` has a conflict marker that's not indented.
There's only one there, so hopefully it won't be too much of a pain to deal with.

I also indented other strings in `test_conflicts.rs`. IMO, this looks nice and
more consistent with the `insta::assert_snapshot` output. I didn't spend the
time to do the same for `test_resolve_command`.
2024-03-22 23:27:25 -07:00
Aleksey Kuznetsov
d8c84940d9 cli: avoid bad hint "Prefix the expression with 'all'..."
There is no point of showing the hint for non-existent revision.

Also appends ':' to the 'all' to make the hint more precise.

#2451
2024-03-23 10:05:18 +05:00
Yuya Nishihara
00285be7a7 formatter: use write!() or writeln!() thoroughly, remove .write_str()
One less Formatter API.
2024-03-23 10:43:38 +09:00
Yuya Nishihara
911cf4b8f6 templater: remove Context type from TemplateLanguage/Property
Now a compiled template doesn't have a static Context type internally. A
property is basically of "Fn() -> Result<O, _>" type, and a type-erased "self"
variable will be injected as needed.

Template<C> types will be refactored separately.
2024-03-22 11:51:15 +09:00
Yuya Nishihara
0fad9c9795 templater: remove now unused TemplatePropertyFn wrapper 2024-03-22 11:51:15 +09:00
Yuya Nishihara
cecae849aa templater: don't define TemplateLanguage::Context statically
In short, this enables compilation of template of e.g. Vec<Commit> type by
using CommitTemplateLanguage.

A Template<C> was originally compiled for a specific type C, and invoked as
"Fn(&C) -> _". It was simple and intuitive, but we had to define the context
type C statically. Things got even worse by extensions support because we had
to provide object-safe hook point for each context type C.

This patch basically removes the Context type from compiled templates. The
"self" variable is injected through RefCell<Option<C>> placeholder. A compiled
template knows its "self" type, but the type can be decided per instance, not
per TemplateLanguage type. A drawback is that the "self" variable will have to
be cloned one more time.

The Template<C> abstraction no longer makes sense, and will be split to inner
Template<()> implementations (which usually represent printable types) and the
outer Template<C>.
2024-03-22 11:51:15 +09:00
Yuya Nishihara
7b641c0236 templater: add Template<C> adapter that evaluates Template<()> with value of C
The idea is basically the same as list.map(|x| ...) template. It compiles the
inner template with a placeholder variable of type 'C', and evaluate it for
each instance variable by injecting the variable through RefCell.
2024-03-22 11:51:15 +09:00
Yuya Nishihara
017026148b generic_templater: clone &Context to Self_ property like other languages
This prepares for removal of TemplateLanguage::Context type. "C: Clone" trait
bounds looked messy, but they can be removed soon.
2024-03-22 11:51:15 +09:00
Yuya Nishihara
915e75efc0 generic_templater: remove &language argument from keyword functions
Because GenericTemplateLanguage doesn't support any global resources, it no
longer makes sense to pass the language instance around to 0-ary keyword
functions.
2024-03-22 11:51:15 +09:00
Yuya Nishihara
2916bbbec5 templater: allow use of wrap_<type>() functions without borrowing &language
These .wrap_<type>() functions aren't supposed to capture resources from the
language instance. It was convenient that wrap_() could be called without fully
spelling the language type, but doing that would introduce lifetime issue in
later patches.

I added type alias L to several places because the language type is usually
called L in generic code.
2024-03-22 11:51:15 +09:00
Anton Älgmyr
e2eb5bddf9 Make node symbols templatable in the graphs.
Adds config options
* templates.log_graph_node
* templates.log_graph_node_elided
* templates.op_log_graph_node
2024-03-21 17:41:31 +01:00
Martin von Zweigbergk
e51878f4fd cli: show timestamp in local timezone and without millis and offset
As discussed in #2900, the milliseconds are rarely useful, and it can
be confusing with different timezones because it makes harder to
compare timestamps.

I added an environment variable to control the timestamp in a
cross-platform way. I didn't document because it exists only for tests
(like `JJ_RANDOMNESS_SEED`).

Closes #2900
2024-03-20 07:54:08 -07:00
Ilya Grigoriev
4fbe6aecc9 clippy: remove some unused code beta clippy/rustc compain about
There are still some warnings from (seemingly) clippy bugs. Quoting
myself from Discord:

> PSA: the latest beta cargo clippy (from Rust 1.78) has some problems
> that affect jj: https://github.com/rust-lang/rust-clippy/issues/12467
> and https://github.com/rust-lang/rust-clippy/issues/12377.  You could
> disable clippy::assigning_clones and clippy::empty_docs as a workaround.
> VS Code can disable them in rust-analyzer, you can also use
> https://github.com/ericseppanen/cargo-cranky (you can put Cranky.toml in
> the per-user gitignore).
2024-03-19 18:33:29 -07:00
Yuya Nishihara
54bb3b4114 cli: remove last use of resolve_multiple_nonempty_revsets() from cmd_run() 2024-03-18 18:23:03 +09:00
Tom Ward
933150d819 cli: allow colors in form #rrggbb
Changes the formatter to accept not only existing color names (such as "red" or
"green") but also those in the form #rrggbb, where rr, gg, and bb are two-digit
hexadecimal numbers. This allows much finer control over colors used.
2024-03-18 08:03:31 +00:00
Yuya Nishihara
3ffe3d9ed8 git-push: warn unmatched revision set per "-rREVISIONS" argument
If -rREVISIONS is specified, the user would probably expect the set contains
at least one local branch.
2024-03-18 09:32:43 +09:00
Yuya Nishihara
8de3932bda git-push: narrow search space of -rREVISIONS 2024-03-18 09:32:43 +09:00
Yuya Nishihara
bc7a42a00e git-push: do not error out on empty revision set
"-r REVISIONS" here specifies the search space of the branches to push, and
warned if no branches are found in that space. I don't think an empty set
should be an error, but a warning for consistency. The warning message will be
improved by the subsequent patches.
2024-03-18 09:32:43 +09:00
Yuya Nishihara
02c0927734 git-push: extract function that looks up branches by revisions
cmd_git_push() is large. Let's split it up.
2024-03-18 09:32:43 +09:00
Yuya Nishihara
4e9d35d049 cli: make "abandon" not fail with empty revset
This command belongs to the same category as "duplicate".

We might want a plural version of resolve_revset(), but I'm not sure whether
it should return Vec<Commit> or Revset. Let's revisit it later when we get
more callers.
2024-03-18 09:32:35 +09:00
Yuya Nishihara
f678ba08cf cli: make "duplicate none()" exit successfully
Per discussion in
https://github.com/martinvonz/jj/pull/3311#discussion_r1527171058

We can also rely on the default "Nothing changed." handling, but it seems
better to state the input set is empty.
2024-03-18 09:32:35 +09:00
Yuya Nishihara
f46b738f6e cli: include root() in the heads node of the immutable set expression
It helps to optimize '~immutable()' to '(immutable_heads() | root())..'.
2024-03-17 14:50:48 +09:00
Yuya Nishihara
50363419fb revset: substitute '~(::x)' to 'x..'
Suppose we have an alias 'immutable()' = '::immutable_heads()', user can
express (visible) mutable set as '~immutable()'. 'immutable_heads()..' can
terminate early, but a generic difference 'all() & ~immutable()' can't.
2024-03-17 14:50:48 +09:00
Yuya Nishihara
9207314173 revset: add substitution rule for "::x & ~(::y-)"
Suppose the generation value is usually small, it should be faster to do
bounded range look up first 'y-', then walk ancestors with the unwanted set
'y-..x'.
2024-03-17 14:50:48 +09:00
Yuya Nishihara
b2194d7d2b cli: use present tense "duplicate" in transaction description 2024-03-17 11:44:41 +09:00
Yuya Nishihara
dc7d1beff3 cli: remove .unwrap() from cmd_duplicate() and simplify new commits mapping 2024-03-17 11:44:41 +09:00
Yuya Nishihara
4e3c772428 cli: make "duplicate" evaluate source revisions all at once
There's a subtle behavior change that an empty revset is no longer rejected
individually, but I think that's good for "jj duplicate".

cmd_duplicate() was the last caller of index.topo_order().
2024-03-17 11:44:41 +09:00
Yuya Nishihara
a1b3b3c547 cli: extract helper that concatenates multiple revision args
I'm going to add one more callers.
2024-03-17 11:44:41 +09:00
dploch
d832b4488c operation_templater: support extensions of the template language 2024-03-16 10:32:53 -04:00
Martin von Zweigbergk
c55e08023e workspace: don't lose sparsed-away paths when recovering workspace
When an operation is missing and we recover the workspace, we create a
new working-copy commit on top of the desired working-copy commit (per
the available head operation). We then reset the working copy to an
empty tree because it shouldn't really matter much which commit we
reset to. However, when the workspace is sparse, it does matter, as
the test case from the previous patch shows. This patch fixes it by
replacing the `reset_to_empty()` method by a new `recover(&Commit)`,
which effectively resets to the empty tree and then resets to the
commit. That way, any subsequent snapshotting will result keep the
paths from that tree for paths outside the sparse patterns.
2024-03-16 07:30:36 -07:00
Martin von Zweigbergk
ffb12680a6 tests: demonstrate sparsed-away paths lost on stale-workspace recovery
As shown by the updated test case, when we recover from a working copy
pointing to a lost operation, the new working-copy commit after
snapshotting will have lost any files outside the sparse patterns.
2024-03-16 07:30:36 -07:00
Martin von Zweigbergk
0d197791a0 tests: add unsnapshotted changes in secondary workspace in recovery test
This adds modifed, removed, and added files in the secondary working
copy.
2024-03-16 07:30:36 -07:00
Martin von Zweigbergk
df9434bd4b tests: use short commit ids in workspace tests
It doesn't look like we need the full ids for anything and the full
ids are especially distracting in the test that uses the native
backend.
2024-03-16 07:30:36 -07:00
Alexis (Poliorcetics) Bourget
93c707a469 lib: improve error message for invalid string pattern, suggesting to use one of the known one 2024-03-16 14:22:16 +01:00
Ilya Grigoriev
8600750fce merge tools: split DiffEditWorkingCopies from DiffWorkingCopies
As suggested by @yuja in https://github.com/martinvonz/jj/pull/3296#discussion_r1525829712
2024-03-15 21:35:57 -07:00
Ilya Grigoriev
6a63c705aa merge tools: rename variable to make diff for the next commit simpler 2024-03-15 21:35:57 -07:00
Yuya Nishihara
429cdb38d7 cli: don't bury GitImportError sources
#3301
2024-03-16 12:51:18 +09:00
Yuya Nishihara
a6ee51a998 cli: move revset::optimize() invocation from parse() to evaluate()
AST substitution is technically closer to parsing, but the parsed expression
can be modified further by caller. So I think it's better to do optimize() in
later pass.

revset_util::parse() is inlined.
2024-03-16 10:28:27 +09:00
Yuya Nishihara
70a2a44f42 cli: ensure revset bench does not include cost of short-prefixes computation
Spotted while moving revset::optimize() around. Since we don't include the
parsing cost of the target expression, we shouldn't include parsing/evaluation
cost of the short-prefixes either. The IdPrefixContext is currently populated
by WorkspaceCommandHelper::new(), but it's hard to tell.
2024-03-16 10:28:27 +09:00
Yuya Nishihara
97cf16c77d cli: use unresolved root() when constructing immutable set expression
The immutable set expression has to be resolved anyway, so it's simpler to
use RevsetExpression::root().
2024-03-16 10:28:27 +09:00
Yuya Nishihara
82b6d073f1 templater: migrate global functions to table-based lookup
The original plan was to extend the globals table to implement "revset(expr)".
I'm not sure if that's more discoverable than "self.contained_in(revset_expr)"
method, but we can decide that later. Anyways, this patch adds typo suggestion
for global functions.
2024-03-16 10:28:19 +09:00
Yuya Nishihara
85f2f3a439 templater: generalize merge_fn_map() helper
The global function type is slightly different from method calls.
2024-03-16 10:28:19 +09:00
Yuya Nishihara
fa9cb72445 templater: dispatch global functions through TemplateLanguage trait
Prepares for migrating to table-based lookup. It's unlikely that the
implementor handles global function calls differently, but the core doesn't
have an access to the customized symbol table.
2024-03-16 10:28:19 +09:00
Yuya Nishihara
1e8bf8426c templater: consolidate auto labeling into build_expression()
Now almost all build_*() functions return L::Property, so it seems more
consistent to do labeling in one place.
2024-03-16 10:28:19 +09:00
Yuya Nishihara
5ec56fb3e9 templater: inline build_method_call()
I don't think this function will grow to unmaintainable size, and I'm going
to add global function dispatcher there.
2024-03-16 10:28:19 +09:00
Ilya Grigoriev
0120cf994b external diff editor: move utility functions to a new file
This is preparation for #3292, which will use these functions. The main
goal is to merge the parts of #3292 that are likely to cause merge
conflicts with other PRs while I polish it up.
2024-03-15 12:30:37 -07:00
Ilya Grigoriev
d5a4891b49 external diff editor: extract functions to populate and delete JJ_INSTRUCTIONS
This will be reused for integration with the new `:builtin-web` diff editor in #3292.

`instructions-path_to_cleanup` is moved into DiffWorkingCopies.

DiffWorkingCopies: add instructions_path_to_cleanup
2024-03-15 12:30:37 -07:00
Martin von Zweigbergk
3bb9fd412a debug-tree: allow looking up tree by path and id, not just revision
Sometimes only a tree has been created, so we shouldn't require a
commit for `jj debug tree`.
2024-03-14 23:28:59 -07:00
Khionu Sybiern
3bbc3e5715 docs: add FAQ for why to use new-then-amend over edit 2024-03-14 11:32:53 -07:00
Khionu Sybiern
289b9bc71f cli: update help message for jj edit
This change updates the language of `jj edit`'s help message to be
more clear as to the nature of the command. It also adds a 
recommendation for a more idiomatic/safer workflow.
2024-03-14 11:32:53 -07:00
Yuya Nishihara
e3303efcf3 cli_util: inline WorkspaceCommandHelper::check_non_empty()
It's simple, and has no data dependency.
2024-03-14 23:51:21 +09:00
Yuya Nishihara
218b1c6c16 commit_templater: add self.immutable() method
I don't know how immutable revisions should be labeled by default, but users
can customize templates whatever they like.
2024-03-14 22:59:43 +09:00
Yuya Nishihara
04d5f59cbb templater: do not rewrite non-argument errors raised from self methods
I'm going to add new "self.immutable()" method, which takes no arguments but
can fail if the configured revset is wrong.
2024-03-14 22:59:43 +09:00
Yuya Nishihara
78104b5e82 cli: extract function that stringifies RevsetParseError 2024-03-14 22:59:43 +09:00
Yuya Nishihara
34eb446037 cli: remove CommandError dependency from revset_util::evaluate()
This function will be called from the templater.
2024-03-14 22:59:43 +09:00
Yuya Nishihara
7dfe04134d cli: check invalid declaration of immutable_heads() alias earlier
I just wanted to remove CommandError from parse_immutable_expression(), which
will be called from the templater, but the new error message looks also better.
2024-03-14 22:59:43 +09:00
Yuya Nishihara
8235e458ed cli: extract primitives for user revset parsing and evaluation
Some of them will be called directly from the commit templater which shouldn't
know WorkspaceCommandHelper. All parameters are passed as function arguments
instead of having a nicer wrapper struct. That's because some resources (e.g.
repo and id prefix context) are also used for different purposes, and it seemed
uneasy to introduce high-level abstraction satisfying all the use cases.
2024-03-14 22:59:43 +09:00
Yuya Nishihara
5806dbfd32 revset_graph: detach CompositeIndex, reimplement as RevWalk
For API consistency. It wouldn't practically matter unless we want to reuse
.iter_graph() in lazy event-driven GUI context.

I don't see significant performance difference:
- jj-0: original impl with look-ahead IndexEntry<'_> buffer
- jj-1: this patch

With dense graph
```
% hyperfine --sort command --warmup 3 --runs 10 -L bin jj-0,jj-1 \
  "target/release-with-debug/{bin} -R ~/mirrors/git --ignore-working-copy log -r.. -T ''"
Benchmark 1: target/release-with-debug/jj-0 -R ~/mirrors/git --ignore-working-copy log -r.. -T ''
  Time (mean ± σ):      1.367 s ±  0.008 s    [User: 1.261 s, System: 0.105 s]
  Range (min … max):    1.357 s …  1.380 s    10 runs

Benchmark 2: target/release-with-debug/jj-1 -R ~/mirrors/git --ignore-working-copy log -r.. -T ''
  Time (mean ± σ):      1.344 s ±  0.017 s    [User: 1.245 s, System: 0.099 s]
  Range (min … max):    1.313 s …  1.369 s    10 runs

Relative speed comparison
        1.02 ±  0.01  target/release-with-debug/jj-0 -R ~/mirrors/git --ignore-working-copy log -r.. -T ''
        1.00          target/release-with-debug/jj-1 -R ~/mirrors/git --ignore-working-copy log -r.. -T ''
```

With sparse graph
```
% hyperfine --sort command --warmup 3 --runs 10 -L bin jj-0,jj-1 \
  "target/release-with-debug/{bin} -R ~/mirrors/git --ignore-working-copy log -r'tags()' -T ''"
Benchmark 1: target/release-with-debug/jj-0 -R ~/mirrors/git --ignore-working-copy log -r'tags()' -T ''
  Time (mean ± σ):      1.347 s ±  0.017 s    [User: 1.216 s, System: 0.130 s]
  Range (min … max):    1.321 s …  1.379 s    10 runs

Benchmark 2: target/release-with-debug/jj-1 -R ~/mirrors/git --ignore-working-copy log -r'tags()' -T ''
  Time (mean ± σ):      1.379 s ±  0.023 s    [User: 1.238 s, System: 0.140 s]
  Range (min … max):    1.328 s …  1.403 s    10 runs

Relative speed comparison
        1.00          target/release-with-debug/jj-0 -R ~/mirrors/git --ignore-working-copy log -r'tags()' -T ''
        1.02 ±  0.02  target/release-with-debug/jj-1 -R ~/mirrors/git --ignore-working-copy log -r'tags()' -T ''
```
2024-03-14 10:07:19 +09:00
Martin von Zweigbergk
93f651d597 next/prev: make first line of help text consistent
This drops the trailing period for consistency with other commands,
and rephrases them a bit for consistency between each other.
2024-03-13 11:11:20 -07:00
Yuya Nishihara
a3839cdf47 commit_templater: allow extension methods to capture repo 2024-03-14 00:00:18 +09:00
Yuya Nishihara
9b42c81d6f templates: add missing "\n" to builtin "root" output 2024-03-13 23:29:27 +09:00
Martin von Zweigbergk
800f0f0347 squash: accept multiple --from revisions
Now you can do e.g. `jj squash --from 'foo+::' --into foo` to squash a
whole series into one commit. It doesn't need to be linear; you can
squash a bunch of siblings into another siblings, for example.
2024-03-13 05:21:05 -07:00
Martin von Zweigbergk
f3e35f1da4 description_utils: teach combine_messages() to handle more than two sources
I plan to teach `jj squash --from` to accept a revset as input.
2024-03-13 05:21:05 -07:00
Martin von Zweigbergk
2b8988c620 description_util: make combine_messages() not handle abandoned commit
I'm going to teach the function to support combining more than two
descriptions.
2024-03-13 05:21:05 -07:00