I'm going to rewrite the error output to print source chain one by one.
The "{message}: {err}" pattern is wrapped in an error struct. InternalError
variant could be a { message, source } pair, but not all errors need an
additional message. This will also apply to UserError.
This prevents rust doctests from trying to compile the code blocks.
I don't think we use doctests much or at all, but I'd like
`cargo insta test --test-runner nextest --accept --workspace`
to pass.
Unfortunately, this affects the output of `jj help` as well, but I
can't think of a workaround for that.
This uses the [`clap-markdown`] library. It's not very flexible, but seems to
work. Its implementation is not difficult. If needed, we could later
reimplement the part that iterates over all subcommands and have a different
output (e.g., the boring version of each help text inside its own code block,
or a different file per subcommand, or some fancy template in handlebars or
another rust-supported templating language). I don't want to do it right now,
though.
The library does turn out to have some annoying bugs, e.g.
https://github.com/ConnorGray/clap-markdown/pull/18, but I think that's not a
deal-braker. The fix seems to be 3 lines; if the fix doesn't get merged soon, we
could vendor the library maybe?
[`clap-markdown`]: https://docs.rs/clap-markdown/latest/clap_markdown/
GitBackend::gc() will need to check if a commit is reachable from any
historical operations. This could be calculated from the view and commit
objects, but the Index will do a better job.
The "::HEAD" set is usually smaller than "::git_refs". If these sets were
imported in that order, "HEAD..git_refs" commits would be indexed on top of
the "::HEAD" commits. It's not a problem, but undesirable.
I'm going to make WorkspaceCommandHelper::maybe_snapshot() snapshot the working
copy before importing refs. git::import_some_refs() can rebase the working copy
branch and therefore @ can be moved. git::import_head() doesn't, and it should
be invoked before snapshotting.
git::import_head() is inserted to some of the git:import_refs() callers where
HEAD seems to matter. I feel it's a bit odd that the HEAD ref is imported to
non-colocated repo, but "jj init --git-repo" relies on that, and I think the
existence of HEAD@git is harmless. It's merely a ref to the revision checked
out somewhere else.
This is a convenient command, for scripting things like `cd $(jj root)
&& do something`, and it seems better to allow people to find it
before they learn about workspaces.
This goes with `c`, `s`, `f`. I feel like it's a relatively
common command now that `auto-local-branch` defaults to
`false`.
I didn't add `u` for `untrack` because it seems a little
ambiguous (un-what?); there may be other `branch` commands that undo
something in the future.
The count() function in this trait is used by "jj branch" to determine
(and then report) how many commits a certain branch is ahead/behind
another branch. This is currently implemented by walking all commits
in the revset, counting how many were encountered. But this could be
improved: if the number is large, it is probably sufficient to report
"at least N" (instead of walking all the way), and this does not scale
well to jj backends that may not have all commits present locally (which
may prefer to return an estimate, rather than access the network).
Therefore, add a function that is explicitly documented to be O(1)
and that can return a range of values if the backend so chooses.
Also remove count(), as it is not immediately obvious that it is an
expensive call, and callers that are willing to pay the cost can obtain
the exact same functionality through iter().count() anyway. (In this
commit, all users of count() are migrated to iter().count() to preserve
all existing functionality; they will be migrated to count_estimate() in
a subsequent commit.)
"branch" needed to be updated due to this change. Although jj
is currently only available in English, I have attempted to keep
user-visible text from being assembled piece by piece, so that if we
later decide to translate jj into other languages, things will be easier
for translators.
A subsequent commit will teach more variants of ahead/behind messages,
so refactor the existing code to avoid code duplication and a future
combinatorial explosion.
Gerrit also needs to be able to push low-level refs into upstream remotes, just
like `jj git push` does. Doing so requires providing callbacks e.g. for various
password entry mechanisms, which was private to the `git` command module.
Pull these out to a new module `git_utils` so we can reuse it across the two
call sites.
This also moves a few other strictly Git-related functions into `git_utils`
as well, just for the sake of consistency.
Signed-off-by: Austin Seipp <aseipp@pobox.com>
* Move canonicalization of the external git repo path into the Workspace::init_git_external().
This keeps necessary code together.
* Add a new variant of WorkspaceInitError for reporting path not found errors. The user error
string is written to pass existing tests.
We've had the public_heads for as long as we've had the View object,
IIRC (I didn't check), but we still don't use it for anything. I don't
have any concrete plans for using it either. Maybe our config for
immutable commits is good enough, or maybe we'll want something more
generic (like Mercurial's phases). For now, I think we should simplify
by removing it the storage for public heads.
This function respects --ignore-working-copy and --at-op arguments, but the
name snapshot() sounds like it could forcibly trigger the snapshotting. Let's
clarify the actual behavior.
import_git_refs_and_head() and snapshot_working_copy() are unchecked functions,
and there are no external callers.
When debugging behavior of badly-GCed repos, I find it's annoying that "op log"
fails because the index can't be loaded. Since "op log" doesn't need a repo, I
think it's better to display the exact op-heads state without merging.
I'm going to make "op log" not load a repo nor resolve concurrent operations,
so there will be the case where no unique "current" operation exists. Since the
"current" operation represents the repo to be loaded, I think it's better to
not consider multi-head operations as the "current" ones. That's why the
templater field isn't Vec<_> but Option<_>.
If indexing failed due to missing commit objects, the repo won't be loadable
without --ignore-working-copy (at least in colocated environment.) In that
case, we can use "op abandon" to recover, but we had to work around the failed
index loading by --ignore-working-copy. Since "op abandon" isn't a repo-level
command, it's better to bypass working-copy snapshot and import of git refs at
all.
--at-op is rejected because it's useless and we'll need extra care for "@"
expression resolution and working-copy updates.
The formatting is closer to hg than git just because it's easier to
conditionalize the whole line per keyword. Our template language doesn't
have infix logical operators.
Unlike the other default templates, all remote branches are displayed because
it's "detailed" output.
Closes#2509