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.
Now that we return the written commit from `write_commit()`, let's
make the timestamps match what was actually written, accounting for
the whole-second precision and the adjustment we do to avoid
collisions.
The internal backend at Google doesn't let you write any value you
want for in the committer field. The `Store` type still caches the
value it attempted to write, which gets a little weird when the
written value is not what we tried to write. We should use the value
the backend actually wrote. However, we don't know if the backend
changed anything without reading the value back, which is often
wasteful. This commit changes the API to return the written value.
I only changed the signature of `write_commit()` for now. Maybe we
should make a similar change to `write_tree()`.
This has several advantages:
* Makes it possible to downcast to non-Git custom backends (might be
useful at Google, but we haven't needed it yet)
* Lets us access more specific functionality on the `GitBackend`,
making it possible to access the `git2::Repository` without
creating a copy of it.
* Removes the dependency on Git from the backend
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.
In large repos, the unique prefixes can get somewhat long (~6 hex
digits seems typical in the Linux repo), which makes them less useful
for manually entering on the CLI. The user typically cares most about
a small set of commits, so it would be nice to give shorter unique ids
to those. That's what Mercurial enables with its
`experimental.revisions.disambiguatewithin` config. This commit
provides an implementation of that feature in `IdPrefixContext`.
In very large repos, it can also be slow to calculate the unique
prefixes, especially if it involves a request to a server. This
feature becomes much more important in such repos.
I would like to copy Mercurial's way of abbreviating ids within a
user-configurable revset. We would do it for both commit ids and
change ids. For that feature, we need a place to keep the set of
commits the revset evaluates to. This commit adds a new
`IdPrefixContext` type which will eventually be that place. The new
type has functions for going back and forth between full and
abbreviated ids. I've updated the templater to use it.
I want to store some lazily calculated data associated with a
repo. The data will depend on the user's config, which means it
shouldn't live in the `ReadonlyRepo` itself. We could store it
directly in `WorkspaceCommandHelper` - and I did that at first - but
it's annoying and risky to remember to reset the cached data when we
update the repo instance (which we do when a transaction
finishes). This commit therefore introduces a wrapper type where we
can store it. Having a wrapper also means that we can use `OnceCell`
instead of more manually initializing it with a `RefCell`.
When creating `RevsetExpression` programmatically, I think we should
use commit ids instead of symbols in the expression. This commit adds
a check for that by using a `SymbolResolver` that always errors
out.
I would eventually want the `SymbolResolver` to be customizable (in
custom `jj` binaries), so we want to make sure we always use the
customized version of it.
I left `RevsetExpression::resolve()` unchanged. I consider that to be
for programmatically created expressions.
I'd like to make the symbol resolution more flexible, both so we can
support customizing it (in custom `jj` binaries) and so we can use it
for resolving short prefixes within a small revset.
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.
IIUC, the consensus in the Git project is that the overloaded nature
of `git checkout` for many use cases was a mistake, and `git
switch/restore` are meant to replace it.
Allows automatic recovery when encountering stale lockfiles, and more
efficient blocking rather than polling for fresh ones. The previous
implementation is preserved for other platforms.
We currently say that `x..y` is "Ancestors of `y` that are not also
ancestors of `x`, both inclusive.". However, it's easy to think that
"both inclusive" means that both `x` and `y` are included in the set,
which is not the case. What we mean is more like "{Ancestors of `y`,
including `y` itself} that are not also {ancestors of `x`, including
`x` itself}.". Given that we already define ancestors and descendants
as being inclusive on the lines above, and we also give the equivalent
expressions using the `x:` and `:y` operators, it's probably best to
just skip the "both inclusive" parts.