Tracking Issue for `git2` deprecation
There has been a latent sentiment amongst contributors that jj has outgrown its need to depend on libgit2, and as such we are moving to replace it and eventually deprecate it. This issue tracks the reasoning for this move, as well as the steps needed to make it happen and a deprecation plan.
Steps
- [x] Implement shelling out to a git subprocess for
push/fetch. #5228 - [x] Migrate remote operations with
gitoxide. - [x] Migrate git tests to
gitoxide- #5639
- #5757
- #5754
- #5655
- #5813
- #5803
- #5770
- #5846
- [x] Switch the default
push/fetchcode path to use thegitsubprocess #5652 - [x] Barricade the
git2code behind a (enabled by default) feature flag #5956 - [x] Enable a deprecation warning for
git2https://github.com/jj-vcs/jj/pull/6047 - [ ] Remove
git2https://github.com/jj-vcs/jj/pull/6048
Outstanding bugs
We list here bugs that have arisen with git subprocessing. Although sometimes git2 might not be the solution (some of them were use-cases that were wholly blocked by git2), it is good to have them registered and try to figure them out before we fully deprecate git2.
- authentication problems
- [ ] #5924
- [ ] #5760
- [x] #5968
- git-push ref failures
- [x] #5978
Rationale
Issues with git2
libgit2 (with git2 being its Rust bindings) is a project to implement git as a library so that external applications can interact programmatically with git repos without having to shell out to git and parse its output.
This effort is commendable and git2 has been crucial in making jj git compatible from the get go. I'd like to emphasize that this is by no means a bash on libgit2. However, we have found some pain points with its usage:
- Missing support for
SSH. This regularly comes up when users try to push to Github, with over 20 issues opened about it forjjplus multiple reports a week. - Packaging problems.
libgit2only supports one version at a time, meaning packagers have a problematic window of time whilejjhas not updatedgit2to its latest version. - Performance. For the main (current) usage of
libgit2, which is interacting withgitremotes,libgit2has been reported to be slow.
Change to what
jj actually uses another git library to interact with repositories: gitoxide. This means that, as it stands, we have two libraries for interacting with git, which is arguably one too many.
As gitoxide has become more feature complete, relying on git2 becomes less desirable.
For the remaining cases (which turn out to be simply the push/fetch operations), the consensus is to rely on shelling out to a git subprocess.
Barricade the git2 code behind a (enabled by default) feature flag
I think this is optional, and can be omitted unless required by package maintainers who want to drop libgit2 earlier.
I think this is optional, and can be omitted unless required by package maintainers who want to drop libgit2 earlier.
Agree that it's not super important. Besides the use case you've described, it'd make adding more git2 code harder, which would be desirable at that stage of the pipeline
I have remote management fully ported locally and will send a PR tomorrow.
I think supporting/testing a feature flag would be nice because it would keep us honest about the ability to drop it.
I’m curious if will use this library in the future:
https://lore.kernel.org/git/[email protected]/
This was already discussed in the Discord, and it will probably be done whenever a version of it will be available.
This doesn't affect anything here, but I wanted to add in another issue with fetching via libgit2: at Mozilla, we're currently using a git plugin to communicate with a mercurial remote. The plugin modifies the repository URL syntax in a way that libgit2 (or jj using libgit2?) doesn't support. (Example: hg::https://hg.mozilla.org/mozilla-central). As a result, we've all been using manual git fetch instead of jj git fetch. This is no longer necessary with git.subprocess = true, and besides is only a temporary measure until we migrate the repository of record from mercurial -> git, but it's still a pain point where the git shell command can be modified to support things that libgit2 does not.
(That said, I assume gitoxide or cgit-rs would have the same issue? As long as the subprocess option is available, it doesn't actually matter for us.)
git.subprocess = true is due to be default in the next stable release now that https://github.com/jj-vcs/jj/pull/5652 has been merged, so hopefully that will eliminate that particular pain point. (Though of course that’s no guarantee it’ll ship if there are issues.)
gix doesn’t implement pushing, so being able to use it for remote operations is not on any imminent horizon. I assume that any future use of cgit-rs should be able to be 1:1 compatible with what git(1) does, but I imagine that’s a way off as well. I think we’ll be using a git(1) subprocess for a fairly long time. (Probably longer than Mozilla will be using Mercurial, from my understanding, at least!)
I've been loving finally using jj this week with GitLab and HTTP since #469 was resolved.
I just wanted to add a reminder here that https://github.com/jj-vcs/jj/blob/main/docs/git-compatibility.md#supported-features could probably use a refresh when some of the dust settles (especially the first 2 bullets: Configuration and Authentication)
Thanks for all the great work here!
I think this should be closed as of jj 0.30 or any build from HEAD no longer require git2.