Port all git functionality to use git CLI (#3833)

## Summary

We currently rely on libgit2 for most git-related functionality.
However, libgit2 has long-standing performance issues, as well as lags
significantly behind git in terms of new features. For these reasons we
now use the git CLI by default for fetching repositories
(https://github.com/astral-sh/uv/pull/1781). This PR completely drops
libgit2 in favor of the git CLI for all git-related functionality, which
should allow us to use features such as partial clones and sparse
checkouts in the future for performance.

There is also a lot of technical debt in the current git code as it's
mostly taken from Cargo. Switching to the git CLI *vastly* simplifies
the `uv-git` codebase.

Eventually we might want to look into switching to
[`gitoxide`](https://github.com/Byron/gitoxide), but it's currently too
immature for our use case.
This commit is contained in:
Ibraheem Ahmed
2024-05-30 15:28:48 -04:00
committed by GitHub
parent 85183c1c36
commit 261aa2c70a
16 changed files with 300 additions and 2318 deletions
+4 -12
View File
@@ -11,7 +11,7 @@ use url::Url;
use cache_key::{digest, RepositoryUrl};
use crate::git::GitRemote;
use crate::{FetchStrategy, GitSha, GitUrl};
use crate::{GitOid, GitSha, GitUrl};
/// A remote Git source that can be checked out locally.
pub struct GitSource {
@@ -19,8 +19,6 @@ pub struct GitSource {
git: GitUrl,
/// The HTTP client to use for fetching.
client: Client,
/// The fetch strategy to use when cloning.
strategy: FetchStrategy,
/// The path to the Git source database.
cache: PathBuf,
/// The reporter to use for this source.
@@ -33,7 +31,6 @@ impl GitSource {
Self {
git,
client: Client::new(),
strategy: FetchStrategy::Cli,
cache: cache.into(),
reporter: None,
}
@@ -77,8 +74,7 @@ impl GitSource {
&db_path,
db,
&self.git.reference,
locked_rev.map(git2::Oid::from),
self.strategy,
locked_rev.map(GitOid::from),
&self.client,
)?;
@@ -98,12 +94,8 @@ impl GitSource {
.join("checkouts")
.join(&ident)
.join(short_id.as_str());
db.copy_to(
actual_rev.into(),
&checkout_path,
self.strategy,
&self.client,
)?;
db.copy_to(actual_rev.into(), &checkout_path)?;
// Report the checkout operation to the reporter.
if let Some(task) = task {