aboutsummaryrefslogtreecommitdiff
path: root/src/repo/git/fetch.rs
diff options
context:
space:
mode:
authorMax Audron <audron@cocaine.farm>2024-03-27 13:40:42 +0100
committerMax Audron <audron@cocaine.farm>2024-03-27 13:40:42 +0100
commitf7aca5859b3a40ec00c8789383e8ab84d7821ae6 (patch)
tree9a242aef7f0b0547949f4fefcff97eeaef1af356 /src/repo/git/fetch.rs
parentimplement 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.rs51
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),
+ }
+ }
+}