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.
There were two issues on my end:
1. `known_hosts` doesn't seem to be recognized
2. SSH Agent is ignored despite running
A workaround for 1. is to set the HOME environment variable on Windows, so I added a hint to suggest this. Ideally we would add a `certificate_check` callback to the remote callbacks, but the git2 crate doesn't expose whether the certificate check already succeeded, which makes it useless for this purpose (as we'd be prompting users to accept a certificate even though that certificate is already known to be valid).
As for 2., I changed the behavior from "check SSH Agent if some env variables exist" to "check SSH Agent and only fail if some env variables exist". On Windows SSH Agent doesn't use these env variables (but trying to communicate with it will still work), so now Windows properly works with SSH Agent.
When using a sparse working copy (e.g. with no files at all) and
updating the working copy from the root commit to a commit with
millions of files, we shouldn't have to walk the parts of the diff
that doesn't match the sparse patterns. However, we still do the full
walk because our `Tree::diff()` currently doesn't care about what the
matcher tells us to visit, it only filters out unwanted files after
visiting them. This commit fixes that for the special (but common)
case of matching nothing in a directory.
I tried also adding special handling for when the matcher says that we
should only visit a few entries, but it wasn't clearly better in the
cases I tested it on. I'll keep that patch around and might send it if
I find some cases where it helps.
By setting a higher level by default, we open up to using the other
tracing levels without spamming the user.
I'm not sure if we should set it to ERROR or OFF by default, we let's
try ERROR for now. It shouldn't make any difference since we don't
have any ERROR-level events yet.
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.
`workspace_root` is [canonicalized](41a2855b4f/lib/src/workspace.rs (L119)), but `cwd` [isn't](41a2855b4f/src/cli_util.rs (L581)). When [working with relative paths](41a2855b4f/src/cli_util.rs (L749-L760)), this leads to issues in Windows: canonicalized paths start with `\\?\`, whereas non-canonicalized paths do not. Therefore, paths were formatted canonicalized, and commands did not accept non-canonicalized paths:
```
$ jj st
Parent commit: bdb62c9 canonicalize cwd in cli_util.rs
Working copy : 059c104379cd (no description set)
Working copy changes:
A \\?\C:\github.com\71\jj\.vscode\launch.json
$ jj diff .vscode\launch.json
Error: Path ".vscode\launch.json" is not in the repo
$ jj diff \\?\C:\github.com\71\jj\.vscode\launch.json
Added regular file \\?\C:\github.com\71\jj\.vscode\launch.json:
...
```
With this change:
```
$ jj st
Parent commit: bdb62c9 canonicalize cwd in cli_util.rs
Working copy : 059c104379cd (no description set)
Working copy changes:
A .vscode\launch.json
$ jj diff .vscode\launch.json
Added regular file .vscode\launch.json:
...
```