aboutsummaryrefslogtreecommitdiff
path: root/src/repo/git/fetch.rs
blob: 5f51523176ec3ea894f5257bc2993a469c3c1f29 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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),
        }
    }
}