I think I will find this useful in at least two cases:
1. When you already have a branch pointing to some commit, it's easier
to do `jj git push -r xyz` than `jj git push --branch
push-xyzxyzyxzxyz`.
2. When you have a stack of changes, it's useful to be able to push
all of them at once.
I think we should also update the default behavior of `jj git push` to
be `jj git push -r 'remote_branches()..@'` or something like
that. That removes the ugliness of having a default behavior that the
user can't reproduce using flags. I'll leave that change for a
separate PR.
This was pretty simple. I simplified a bit by making the transaction
description mention only branches, not changes. It still mentions the
branches created for the changes, however. Also, since the operation
"tags" contain the full command line, I think it'll still be
relatively easy for the user to understand what the operation was
about.
I changed `test_early_args` because the first line no longer has a
redundant color reset, so now we test the `Commands:` line instead,
which has actual color (well, bold+underline anyway).
I made a typo and got something like this:
```
Error: Commit or change id prefix "wl" is ambiguous
```
Since we can tell commit ids from change ids these days, let's make
the error message say which kind of id it is. Changing that also kind
of forced me to make a special error for empty strings. Otherwise we
would have to arbitrarily say that an empty string is a commit id or
change id. A specific error message for empty strings seems helpful,
so that's probably for the better anyway.
Since we abuse TOML table syntax to define function aliases, an identical
function alias can be found more than once in the merged config. The merged
config doesn't preserve the definition order, so we need to load aliases
table per layer.
`jj sparse` is a bit different from other commands in that its `jj
sparse --list` is practically a separate command. Let's make it an
actual subcommand for consistency, and so we can more cleanly add
additional flags for `jj sparse list` in the future. I moved all the
other arguments to `jj sparse set`. I'm not sure if `jj sparse set
--reset` would have been better as `jj sparse reset`, but it is
technically just updating the sparse patterns just like the other
arguments (`--clear`, `--add` , `--remove`).
It's easier to follow the test if we try to resolve commits from the
`jj log` output just above. That's what we did until I changed it away
from that without thinking in fcda05c69b.
When I added `revsets.short-prefixes` in 20ef171d7a, I didn't notice
that I made the test of commit prefixes among hidden commits
ineffective because. This restores that by disabling short prefixes in
the test.
This bug concerns the way `import_refs` that gets called by `fetch` computes
the heads that should be visible after the import.
Previously, the list of such heads was computed *before* local branches were
updated based on changes to the remote branches. So, commits that should have
been abandoned based on this update of the local branches weren't properly
abandoned.
Now, `import_refs` tracks the heads that need to be visible because of some ref
in a mapping keyed by the ref. If the ref moves or is deleted, the
corresponding heads are updated.
Fixes#864
Before this, it was difficult to run an integration test after adding any
directives from printf-style debugging to jj (e.g. `err!`, `eprintln!`,
`println!`), since `jj_cmd_success` fails if `jj` to output anything to stderr
while `jj_cmd_failure` fails if stdout is not empty.
This adds a `TestEnvironment::debug_allow_stderr` variable that lifts this
restriction for `jj_cmd_success` and makes it output anything `jj` output to
stderr instead. You can set it directly or by running the test with the
`DEBUG_ALLOW_STDERR` environment variable set. You can then add `err!`
anywhere.
You do need to run the test in a somewhat special way, as described in the
docstring.
This adds a config called `revsets.short-prefixes`, which lets the
user specify a revset in which to disambiguate otherwise ambiguous
change/commit ids. It defaults to the value of `revsets.log`.
I made it so you can disable the feature by setting
`revsets.short-prefixes = ""`. I don't like that the default value
(using `revsets.log`) cannot be configured explicitly by the
user. That will be addressed if we decide to merge the `[revsets]` and
`[revset-aliases]` sections some day.
I plan to add `revsets.short-prefixes` and `revsets.immutable` soon,
and I think `[revsets]` seems like reasonable place to put them. It
seems consistent with our `[templates]` section. However, it also
suffers from the same problem as that section, which is that the
difference between `[templates]` and `[template-aliases]` is not
clear. We can decide about about templates and revsets later.
Before, HEAD@git was at change `e1f4` mentioned in the test. So, as long as we
consider the behavior added in 20eb9ec to be correct, that change should NOT
have been abandoned after the fetch, in spite of what the comment in the test
says. In other words, the test did NOT demonstrate a bug before this commit.
Now, the test properly demonstrates the bug.
Cc #864
The current behavior was introduced by 20eb9ecec1 "git: don't abandon
HEAD commit when it loses a branch." While the change made HEAD mutation
behavior more consistent with a plain ref operation, HEAD can also move on
checkout, and checkout shouldn't be considered a history rewriting operation.
I'm not saying the new behavior is always correct, but I think it's safer
than losing old HEAD branch. I also think this change will help if we want
to extract HEAD management function from git::import_refs().
Fixes#1042.
On "jj checkout", description of the working-copy commit is empty, and the
working-copy parent provides more information. It might be a bit verbose to
print parent summary on every history rewriting, but I think that's okay.
If "jj op undo" doesn't roll back git refs (#1541), test_git_import_undo()
would get weird state. I think these tests are easier to follow than
test_git_fetch_undo() since no remote refs are involved.
"jj show" is basically a "log" command with different defaults. We'll need
to consider this kind of stuff if we want to introduce namespace to templates.
I think we should test actually performing the push when possible. I
think I initially used `--dry-run` because I thought it wasn't
possible to do local pushes with libgit2.
This is a convenience optimization to improve the default user
experience, since `jj log` is a frequently run command. Accessing the
help information explicitly still follows normal CLI conventions, and
instructions are displayed appropriately if the user happens to make a
mistake. Discoverability should not be adversely harmed.
Note that this behavior mirrors what Sapling does [2], where `sl` will
display the smartlog by default.
[1] https://github.com/clap-rs/clap/issues/975
[2] https://sapling-scm.com/docs/overview/smartlog
I wasn't quite happy with `jj support` but I couldn't think of
anything better when I moved the commands from `jj debug` in
e2b4d7058d. Thanks to @ilyagr for suggesting `jj util`.
This makes it clear what should be resolved at resolve_symbols(). Symbol
is a bit special while parsing function arguments, but it's no different
than the other unresolved references at expression level.
This changes the version number reported by `jj version` from "0.7.0"
to something like
"0.7.0-24a512683bc921699575b6a953624b05c068d544a". The hash is added
if running in a jj repo or a git repo.
The `heads()` revset function with one argument is the counterpart to
`roots()`. Without arguments, it returns the visible heads in the
repo, i.e. `heads(all())`. The two use cases are quite different, and
I think it would be good to clarify that the no-arg form returns the
visible heads, so let's split that out to a new `visible_heads()`
function.
The impact of not having configured one's name and email is not apparent from the warning message. Under the Toulmin model:
- Claim (implicit): You should configure your name and email.
- Grounds: Your name and email are not currently configured.
- Warrant (currently missing): Configuring your name and email will let you do...
This serves the role of limit() in Mercurial. Since revsets in JJ is
(conceptually) an unordered set, a "limit" predicate should define its
ordering criteria. That's why the added predicate is named as "latest".
Closes#1110
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.
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.
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'
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.
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?
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.
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.
@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 ◎-`.
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.
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
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.
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>.
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.
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 "~".
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
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)'