Wrapped errors are usually displayed after "Failed to import refs ...", etc., so
the context is obvious. I also removed "Internal"/"Error" for consistency.
I tried to minimize this patch, but it seemed rather complicated than porting
most callers all at once. Remote management functions in git.rs are unchanged.
They'll be ported separately.
With this change, many non-template bookmark/remote name outputs should be
rendered in revset syntax.
We've been finding that a lot of bug reports on `jj git push` come from
sub-standard error reporting on the reasons the failure happens.
It can come from a number of places:
- hook failure
- remote branch protection
- git config
This commit forwards the reason as explained by the ouptut of git push
to help users figure out what is happening.
We need to report more complicated errors on push.
Firstly, we can have a mix of unexpected ref locations and remote
rejections. We should report both at the same time.
Second, git gives us a reason for why a push failed.
For this to work, it's relevant to refactor the current error reporting
path to allow us to inject this information.
I have no immediate plan, but I think we can make "jj git export" show exported
refs. The FailedRefExport type is replaced with a plain tuple since we have a
named type wrapping (symbol, reason) pairs now.
This removes the special case for RefName::LocalBranch(_), which can be
processed as a remote bookmark.
"jj git import" now prints local bookmarks and tags with @git suffix. I think
this is more correct since these refs are imported from the backing Git
repository.
I'm going to reimplement git_ref_filter to process translated remote bookmark
names, and "git" remote will mean the local Git-tracking remote there. The
reserved remote name is checked prior to filtering because refs in that remote
cannot be represented as remote symbols.
I originally implemented the error handling the other way because we didn't
have a machinery to report partial import failure. Now we have stats, it's
easy to report skipped ref names.
This will probably mitigate problems of concurrent updates. If two concurrent
processes tried to import + reset HEAD, one of them should fail.
Closes#3754
With git.subprocess = true, it's more important to skip unneeded remote
operations. Each remote command may involve user intervention if authentication
requires manual step.
This change also means that the remote connection is no longer reused in git2
impl. I think the added cost is acceptable. The git2 impl will hopefully be
removed soon, and the remote branch name is needed only when cloning new repo.
* Make the new `GitFetch` api public.
* Move `git::fetch` to `lib/tests/test_git.rs` as `git_fetch`, to minimize
churn in the tests. Update test call sites to use `git_fetch`
* Delete the `git::fetch` from `lib/src/git.rs`.
* Update `jj git clone` and `git_fetch` in `cli/src/git_utils.rs` to use
the new api directly. Removing one redundant layer of indirection.
* This fixes#4920 as it first fetches from all remotes before `import_refs()`
is called, so there is no race condition if the same commit is treated
differently in different remotes specified in the same command.
Original commit by @essiene
Currently, the Git subprocess tests only work on Linux due to a default
path being used for the `git` executable when `$PATH` is unset. This can
break if Git isn't installed at the expected path. Also, I believe it is
currently necessary to set the `$TEST_GIT_EXECUTABLE_PATH` environment
variable on Windows for tests to pass. Instead, we should use the user's
`$PATH` to locate the `git` executable, as well as any other executables
that are needed. This also makes `$TEST_GIT_EXECUTABLE_PATH` no longer
necessary, so it can be removed.
In some cases, there are non trivial codepaths for fetching multiple
branches explicitly. In particular, it might be the case that fetching
works for n = 2 but not n = 3.
This commit changes a cli test to have 3 remotes and 3 branches, and a
lib test with 3 branches, only one of them succeds.
Instead of setting the index to match the tree of HEAD, we now set the
index to the merged parent tree of the working copy commit. This means
that if you edit a merge commit, it will make the Git index look like it
would in the middle of a `git merge` operation (with all of the
successfully-merged files staged in the index).
If there are any 2-sided conflicts in the merged parent tree, then they
will be added to the index as conflicts. Since Git doesn't support
conflicts with more than 2 sides, many-sided conflicts are staged as the
first side of the conflict. The following commit will improve this.
This will give us more fine-grained control over what files we put in
the index, allowing us to create conflicted index states. We also still
need to use git2 to clean up the merge/rebase state, since gix doesn't
have any function for this currently.
These tests should still pass after we switch to gix for resetting the
index, so we need to make sure they don't rely on the cached index from
the `git2::Repository` instance.
* GitFetch{} separates `fetch()` from `import_refs()`.
* This allows more control over the stages of the fetch so multiple fetches
can happen before `import_refs` resolves the changes in the local jj repo.
* Implement `git::fetch` in terms of the new api.
* Add a test case for initial fetch from a repo without `HEAD` set. This tests
the default branch retrieving behaviour.
Issue: #4923
This test reliably failed if I dropped tv_nsec part from statx().
Since we reload the repo now, several assertions get "fixed". I've added
index().has_id() test to clarify that it's still broken.