Skip to content

Commit

Permalink
Merge branch 'gix-clone-improvements'
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Jan 3, 2023
2 parents 41fc2bb + 6ba799c commit 76c99f3
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
20 changes: 18 additions & 2 deletions git-transport/src/client/blocking_io/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,23 @@ fn supervise_stderr(
Some(err) => Err(err),
None => match res {
Ok(n) if n == wanted => Ok(n),
Ok(n) => self.recv.recv().ok().map(Err).unwrap_or(Ok(n)),
Ok(n) => {
// TODO: fix this
// When parsing refs this seems to happen legitimately
// (even though we read packet lines only and should always know exactly how much to read)
// Maybe this still happens in `read_exact()` as sometimes we just don't get enough bytes
// despite knowing how many.
// To prevent deadlock, we have to set a timeout which slows down legitimate parts of the protocol.
// This code was specifically written to make the `cargo` test-suite pass, and we can reduce
// the timeouts even more once there is a native ssh transport that is used by `cargo`, it will
// be able to handle these properly.
// Alternatively, one could implement something like `read2` to avoid blocking on stderr entirely.
self.recv
.recv_timeout(std::time::Duration::from_millis(5))
.ok()
.map(Err)
.unwrap_or(Ok(n))
}
Err(err) => Err(self.recv.recv().ok().unwrap_or(err)),
},
}
Expand All @@ -153,7 +169,7 @@ fn supervise_stderr(

let (send, recv) = std::sync::mpsc::sync_channel(1);
std::thread::Builder::new()
.name("supervise ssh".into())
.name("supervise ssh stderr".into())
.stack_size(128 * 1024)
.spawn(move || -> std::io::Result<()> {
let mut process_stderr = std::io::stderr();
Expand Down
16 changes: 12 additions & 4 deletions gitoxide-core/src/repository/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3;
pub(crate) mod function {
use std::ffi::OsStr;

use anyhow::bail;
use anyhow::{bail, Context};
use git_repository as git;
use git_repository::{bstr::BString, remote::fetch::Status, Progress};

use super::Options;
use crate::{repository::fetch::function::print_updates, OutputFormat};

pub fn clone<P>(
remote: impl AsRef<OsStr>,
directory: impl AsRef<std::path::Path>,
url: impl AsRef<OsStr>,
directory: Option<impl Into<std::path::PathBuf>>,
overrides: Vec<BString>,
mut progress: P,
mut out: impl std::io::Write,
Expand All @@ -41,8 +41,16 @@ pub(crate) mod function {
bail!("JSON output isn't yet supported for fetching.");
}

let url: git::Url = url.as_ref().try_into()?;
let directory = directory.map(|dir| Ok(dir.into())).unwrap_or_else(|| {
git::path::from_bstr(url.path.as_ref())
.as_ref()
.file_stem()
.map(Into::into)
.context("Filename extraction failed - path too short")
})?;
let mut prepare = git::clone::PrepareFetch::new(
remote.as_ref(),
url,
directory,
bare.then(|| git::create::Kind::Bare)
.unwrap_or(git::create::Kind::WithWorktree),
Expand Down
2 changes: 1 addition & 1 deletion src/plumbing/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ pub mod clone {
pub remote: OsString,

/// The directory to initialize with the new repository and to which all data should be written.
pub directory: PathBuf,
pub directory: Option<PathBuf>,
}
}

Expand Down

0 comments on commit 76c99f3

Please sign in to comment.