diff options
| author | Max Audron <audron@cocaine.farm> | 2024-03-27 13:40:42 +0100 |
|---|---|---|
| committer | Max Audron <audron@cocaine.farm> | 2024-03-27 13:40:42 +0100 |
| commit | f7aca5859b3a40ec00c8789383e8ab84d7821ae6 (patch) | |
| tree | 9a242aef7f0b0547949f4fefcff97eeaef1af356 /src/repo/git/fetch.rs | |
| parent | implement basic cloning and updating with gix (diff) | |
reorganize repo git impls
Diffstat (limited to 'src/repo/git/fetch.rs')
| -rw-r--r-- | src/repo/git/fetch.rs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/repo/git/fetch.rs b/src/repo/git/fetch.rs new file mode 100644 index 0000000..5f51523 --- /dev/null +++ b/src/repo/git/fetch.rs @@ -0,0 +1,51 @@ +use super::{Repo, RepoError}; + +use anyhow::Context; +use gix::{ + interrupt::IS_INTERRUPTED, + progress::Discard, + remote::{fetch::Status, Direction}, +}; + +impl Repo { + #[tracing::instrument(level = "trace")] + pub fn clone(&self, url: &str) -> Result<(), RepoError> { + std::fs::create_dir_all(&self.path).unwrap(); + + let mut prepare_clone = gix::prepare_clone(url, &self.path).unwrap(); + + let (mut prepare_checkout, _) = prepare_clone + .fetch_then_checkout(Discard, &IS_INTERRUPTED) + .unwrap(); + + let (_repo, _) = prepare_checkout + .main_worktree(Discard, &IS_INTERRUPTED) + .unwrap(); + + Ok(()) + } + + #[tracing::instrument(level = "trace")] + pub fn fetch<'a>(&mut self) -> Result<bool, RepoError> { + let remote = self.default_remote()?; + let conn = remote.connect(Direction::Fetch).unwrap(); + let outcome = conn + .prepare_fetch(Discard, gix::remote::ref_map::Options::default()) + .context("fetch: failed to prepare patch")? + .receive(Discard, &IS_INTERRUPTED) + .context("fetch: failed to receive")?; + + match outcome.status { + Status::NoPackReceived { + dry_run: _, + negotiate: _, + update_refs: _, + } => Ok(false), + Status::Change { + negotiate: _, + write_pack_bundle: _, + update_refs: _, + } => Ok(true), + } + } +} |
