The width parameter is mandatory so it wouldn't fall back to ui.term_width() by
mistake. The API is getting messy and we might want to extract some parameters
to separate struct.
Fixes#4158
Suppose cmd_root() will gain options to print other kind of root paths, it's
probably simpler to inline path handling there instead of turning cmd_root()
into a dispatcher function. If cmd_root() remains with the current form, maybe
we can add aliases.root = ["workspace", "root"] instead.
Users may try to run `jj workspace add <name>` without specifying a
path, which results in the workspace being created in the current
directory. This can be confusing, since the workspace contents will also
be snapshotted in the original workspace if it is not sparse. Adding a
warning should reduce confusion in this case.
The high level changes include:
- Reworking `fix_file_ids()` to loop over multiple candidate tools per file,
piping file content between them. Only the final file content is written to
the store, and content is no longer read for changed files that don't match
any of the configured patterns.
- New struct `ToolsConfig` to represent the parsed/validated configuration.
- New function `get_tools_config()` to create a `ToolsConfig` from a `Config`.
- New tests; the only old behavior that has changed is that we don't require
`fix.tool-command` if `fix.tools` defines one or more tools. The general
approach to validating the config is to fail early if anything is weird.
Co-Authored-By: Josh Steadmon <steadmon@google.com>
This implements a building block of "signed-off-by line" #1399 and "commit
--verbose" #1946. We'll probably need an easy way to customize the diff part,
but I'm not sure if it can be as simple as a template alias function. User
might want to embed diffs without "JJ: " prefixes?
Perhaps, we can deprecate "ui.default-description", but it's not addressed in
this patch. It could be replaced with "default_description" template alias,
but we might want to configure default per command. Suppose we add a default
"backout_description" template, it would have to be rendered against the
source commit, not the newly-created backout commit.
The template key is named as "draft_commit_description" because it is the
template to generate an editor template. "templates.commit_description_template"
sounds a bit odd.
There's one minor behavior change: the default description is now terminated
by "\n".
Closes#1354
description_template_for_*() functions will be merged soon.
We don't need to set the default description to the second commit of the split
because its description should be kept empty if it was.
This could be handled by description_template_for_describe(), but I think it's
better to do mutation by caller. I also think commands like "backout" or "new"
can do a similar thing to generate a default commit description from the source
or merge parent commits.
This will help consolidate description_template_for_*() functions and port them
to templater. This change also means the committer (and operation start)
timestamp is set earlier. I think that's good.
It's wrong to deduce loaded_at_head from command-line arguments if the repo was
loaded at an arbitrary operation. Instead, the caller should specify whether
the working copy state is synchronized with the repo view.
I think .for_loaded_repo(ui, workspace, repo, true) would be bad for
readability, so I added separate functions. I'm not happy with the name
.for_temporary_repo(), but it seems okay for the current call sites.
--at-op should be invalid on repo initialization. "init --ignore-working-copy"
could be supported by using working_copy.reset(), but I don't think it's
worth the effort. If the working directory is empty, --ignore-working-copy
is meaningless, and if the directory is not empty, the user would probably
want to do snapshot at some point.
The user can define the setting `git.private-commits` as they desire. For
example:
git.private-commits = 'description(glob:"wip:*")'
If any commits are in this revset, then the push is aborted.
If a commit would be private but already exists on the remote, then it does
not block pushes, nor do its descendents block pushes unless they are also
contained in `git.private-commits`.
Closes#3376
The user probably would expect the path to be relative to their current
directory rather than the workspace root. For instance, if the user is
in a child directory and runs `jj workspace add ../../name`, then they
might be surprised if we printed "../name" instead of "../../name".
Prevents a warning from being printed when renaming branches in a
colocated repo, since git tracking branches were being considered as
remote tracking branches.
Now that `jj move` does not accept `-r` (since it has `--from` and `--to`), `jj set --to` seems more useful
than `jj set -r`. `create --to` is also added for ease of switching
between `branch create` and `branch move`.
Currently, when there is a commit with two predecessors, the graph
splits into two branches, and all of the predecessors on the first
branch are printed before all of the predecessors on the second branch.
This causes the graph to grow wider with each squashed commit, since the
second branch must always get indented one level farther each time a
commit is squashed. I have some commits where the graph is indented more
than 10 levels due to squashing more than 10 times, making it very
difficult to read.
Reversing the order and printing the second branch before the first
branch prevents this unnecessary indentation and makes the graph easier
to read. This does not change the order of the edges in the graph (i.e.
the first predecessor is still the first edge and the second predecessor
is still the second edge in the graph).
Adds support for revset functions `tracked_remote_branches()` and
`untracked_remote_branches()`. I think this would be especially useful
for configuring `immutable_heads()` because rewriting untracked remote
branches usually wouldn't be desirable (since it wouldn't update the
remote branch). It also makes it easy to hide branches that you don't
care about from the log, since you could hide untracked branches and
then only track branches that you care about.
Partially resolve a 1.5‐year‐old TODO comment.
Add opt‐in syntax for case‐insensitive matching, suffixing the
pattern kind with `-i`. Not every context supports case‐insensitive
patterns (e.g. Git branch fetch settings). It may make sense to make
this the default in at least some contexts (e.g. the commit signature
and description revsets), but it would require some thought to avoid
more confusing context‐sensitivity.
Make `mine()` match case‐insensitively unconditionally, since email
addresses are conventionally case‐insensitive and it doesn’t take
a pattern anyway.
This currently only handles ASCII case folding, due to the complexities
of case‐insensitive Unicode comparison and the `glob` crate’s lack
of support for it. This is unlikely to matter for email addresses,
which very rarely contain non‐ASCII characters, but is unfortunate
for names and descriptions. However, the current matching behaviour is
already seriously deficient for non‐ASCII text due to the lack of any
normalization, so this hopefully shouldn’t be a blocker to adding the
interface. An expository comment has been left in the code for anyone
who wants to try and address this (perhaps a future version of myself).
`tx.format_commit_summary()` can be expensive because it needs to build
an IdPrefixContext now, so it's best to avoid formatting instruction
messages unless they are actually required.
For the same reason as the previous commit.
Created and moved stats are printed separately because it's unusual to do both
within one "branch set" invocation.
For the same reason as cdc0cc360162. This will help notice problems like wrong
target revision.
The warning for multiple branches is reorganized as a hint for "-r" option,
which I think is the main purpose of this warning. Unlike "squash", we don't
check if an argument can be parsed as a revset because branch name is usually
a valid symbol expression.
Forgetting a workspace removes its working-copy commit, so it makes
sense for it to be abandoned if it is discardable just like editing a
new commit will cause the old commit to be abandoned if it is
discardable.
It's nice to see the result of "branch move", "create", etc., and this is more
important in "branch move" because the source branches can be specified in an
abstracted way. I originally considered printing a list of affected branches,
but it looked rather verbose. Since the destination revision is unique, we can
use commit_summary template instead.
This patch also removes a warning about multiple branches because the branch
names are included in the commit summary. I think the hint message is good
enough to signal possible mistake.