Skip to content

Commit 6fce683

Browse files
committed
respect --offline flag for git cli operations
closes #12234 # Summary [fetch_with_cli](https://github.com/thejchap/uv/blob/e0f81f0d4a904d8c743e776d9f8c9ef5b96f769c/crates/uv-git/src/git.rs#L573) doesn't respect the registry client's [connectivity setting](https://github.com/thejchap/uv/blob/e0f81f0d4a904d8c743e776d9f8c9ef5b96f769c/crates/uv-client/src/registry_client.rs#L1009) - this pr updates to set when the client's connectivity setting is # Test Plan E2E
1 parent ba443fa commit 6fce683

File tree

5 files changed

+49
-9
lines changed

5 files changed

+49
-9
lines changed

crates/uv-distribution/src/source/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
14561456
.uncached_client(resource.git.repository())
14571457
.clone(),
14581458
client.unmanaged.disable_ssl(resource.git.repository()),
1459+
client.unmanaged.connectivity() == Connectivity::Offline,
14591460
self.build_context.cache().bucket(CacheBucket::Git),
14601461
self.reporter
14611462
.clone()
@@ -1617,6 +1618,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
16171618
.uncached_client(resource.git.repository())
16181619
.clone(),
16191620
client.unmanaged.disable_ssl(resource.git.repository()),
1621+
client.unmanaged.connectivity() == Connectivity::Offline,
16201622
self.build_context.cache().bucket(CacheBucket::Git),
16211623
self.reporter
16221624
.clone()
@@ -1851,6 +1853,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
18511853
git,
18521854
client.unmanaged.uncached_client(git.repository()).clone(),
18531855
client.unmanaged.disable_ssl(git.repository()),
1856+
client.unmanaged.connectivity() == Connectivity::Offline,
18541857
self.build_context.cache().bucket(CacheBucket::Git),
18551858
self.reporter
18561859
.clone()

crates/uv-git/src/git.rs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -230,15 +230,23 @@ impl GitRemote {
230230
locked_rev: Option<GitOid>,
231231
client: &ClientWithMiddleware,
232232
disable_ssl: bool,
233+
offline: bool,
233234
) -> Result<(GitDatabase, GitOid)> {
234235
let reference = locked_rev
235236
.map(ReferenceOrOid::Oid)
236237
.unwrap_or(ReferenceOrOid::Reference(reference));
237238
let enable_lfs_fetch = env::var(EnvVars::UV_GIT_LFS).is_ok();
238239

239240
if let Some(mut db) = db {
240-
fetch(&mut db.repo, &self.url, reference, client, disable_ssl)
241-
.with_context(|| format!("failed to fetch into: {}", into.user_display()))?;
241+
fetch(
242+
&mut db.repo,
243+
&self.url,
244+
reference,
245+
client,
246+
disable_ssl,
247+
offline,
248+
)
249+
.with_context(|| format!("failed to fetch into: {}", into.user_display()))?;
242250

243251
let resolved_commit_hash = match locked_rev {
244252
Some(rev) => db.contains(rev).then_some(rev),
@@ -265,8 +273,15 @@ impl GitRemote {
265273

266274
fs_err::create_dir_all(into)?;
267275
let mut repo = GitRepository::init(into)?;
268-
fetch(&mut repo, &self.url, reference, client, disable_ssl)
269-
.with_context(|| format!("failed to clone into: {}", into.user_display()))?;
276+
fetch(
277+
&mut repo,
278+
&self.url,
279+
reference,
280+
client,
281+
disable_ssl,
282+
offline,
283+
)
284+
.with_context(|| format!("failed to clone into: {}", into.user_display()))?;
270285
let rev = match locked_rev {
271286
Some(rev) => rev,
272287
None => reference.resolve(&repo)?,
@@ -441,6 +456,7 @@ fn fetch(
441456
reference: ReferenceOrOid<'_>,
442457
client: &ClientWithMiddleware,
443458
disable_ssl: bool,
459+
offline: bool,
444460
) -> Result<()> {
445461
let oid_to_fetch = match github_fast_path(repo, remote_url, reference, client) {
446462
Ok(FastPathRev::UpToDate) => return Ok(()),
@@ -516,9 +532,14 @@ fn fetch(
516532

517533
debug!("Performing a Git fetch for: {remote_url}");
518534
let result = match refspec_strategy {
519-
RefspecStrategy::All => {
520-
fetch_with_cli(repo, remote_url, refspecs.as_slice(), tags, disable_ssl)
521-
}
535+
RefspecStrategy::All => fetch_with_cli(
536+
repo,
537+
remote_url,
538+
refspecs.as_slice(),
539+
tags,
540+
disable_ssl,
541+
offline,
542+
),
522543
RefspecStrategy::First => {
523544
// Try each refspec
524545
let mut errors = refspecs
@@ -530,6 +551,7 @@ fn fetch(
530551
std::slice::from_ref(refspec),
531552
tags,
532553
disable_ssl,
554+
offline,
533555
);
534556

535557
// Stop after the first success and log failures
@@ -576,6 +598,7 @@ fn fetch_with_cli(
576598
refspecs: &[String],
577599
tags: bool,
578600
disable_ssl: bool,
601+
offline: bool,
579602
) -> Result<()> {
580603
let mut cmd = ProcessBuilder::new(GIT.as_ref()?);
581604
// Disable interactive prompts in the terminal, as they'll be erased by the progress bar
@@ -591,6 +614,10 @@ fn fetch_with_cli(
591614
debug!("Disabling SSL verification for Git fetch");
592615
cmd.env(EnvVars::GIT_SSL_NO_VERIFY, "true");
593616
}
617+
if offline {
618+
debug!("Offline - setting GIT_ALLOW_PROTOCOL=file");
619+
cmd.env(EnvVars::GIT_ALLOW_PROTOCOL, "file");
620+
}
594621
cmd.arg("--force") // handle force pushes
595622
.arg("--update-head-ok") // see discussion in #2078
596623
.arg(url.as_str())

crates/uv-git/src/resolver.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ impl GitResolver {
109109
url: &GitUrl,
110110
client: ClientWithMiddleware,
111111
disable_ssl: bool,
112+
offline: bool,
112113
cache: PathBuf,
113114
reporter: Option<Arc<dyn Reporter>>,
114115
) -> Result<Fetch, GitResolverError> {
@@ -138,9 +139,9 @@ impl GitResolver {
138139

139140
// Fetch the Git repository.
140141
let source = if let Some(reporter) = reporter {
141-
GitSource::new(url.as_ref().clone(), client, cache).with_reporter(reporter)
142+
GitSource::new(url.as_ref().clone(), client, cache, offline).with_reporter(reporter)
142143
} else {
143-
GitSource::new(url.as_ref().clone(), client, cache)
144+
GitSource::new(url.as_ref().clone(), client, cache, offline)
144145
};
145146

146147
// If necessary, disable SSL.

crates/uv-git/src/source.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub struct GitSource {
2525
client: ClientWithMiddleware,
2626
/// Whether to disable SSL verification.
2727
disable_ssl: bool,
28+
/// Whether to operate without network connectivity.
29+
offline: bool,
2830
/// The path to the Git source database.
2931
cache: PathBuf,
3032
/// The reporter to use for this source.
@@ -37,10 +39,12 @@ impl GitSource {
3739
git: GitUrl,
3840
client: impl Into<ClientWithMiddleware>,
3941
cache: impl Into<PathBuf>,
42+
offline: bool,
4043
) -> Self {
4144
Self {
4245
git,
4346
disable_ssl: false,
47+
offline,
4448
client: client.into(),
4549
cache: cache.into(),
4650
reporter: None,
@@ -110,6 +114,7 @@ impl GitSource {
110114
locked_rev,
111115
&self.client,
112116
self.disable_ssl,
117+
self.offline,
113118
)?;
114119

115120
(db, actual_rev, task)

crates/uv-static/src/env_vars.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,10 @@ impl EnvVars {
492492
#[attr_hidden]
493493
pub const GIT_SSL_NO_VERIFY: &'static str = "GIT_SSL_NO_VERIFY";
494494

495+
/// Set allowed protocols for git operations.
496+
#[attr_hidden]
497+
pub const GIT_ALLOW_PROTOCOL: &'static str = "GIT_ALLOW_PROTOCOL";
498+
495499
/// Disable interactive git prompts in terminals, e.g., for credentials. Does not disable
496500
/// GUI prompts.
497501
#[attr_hidden]

0 commit comments

Comments
 (0)