149 lines · 6.3 KB · Rust
RawDownload
#[cfg(feature = "blocking-network-client")]mod blocking_io {    use std::sync::atomic::AtomicBool;     use git_features::progress;    use git_repository as git;    use git_repository::remote::{fetch, Direction::Fetch};    use git_testtools::hex_to_id;     use crate::remote;     fn repo_rw(name: &str) -> (git::Repository, git_testtools::tempfile::TempDir) {        let dir = git_testtools::scripted_fixture_repo_writable_with_args(            "make_fetch_repos.sh",            [git::path::realpath(remote::repo_path("base"))                .unwrap()                .to_string_lossy()],            git_testtools::Creation::ExecuteScript,        )        .unwrap();        let repo = git::open_opts(dir.path().join(name), git::open::Options::isolated()).unwrap();        (repo, dir)    }     #[test]    fn fetch_empty_pack() -> crate::Result {        let (repo, _tmp) = repo_rw("two-origins");        let mut remote = repo.head()?.into_remote(Fetch).expect("present")?;        remote.replace_refspecs(Some("HEAD:refs/remotes/origin/does-not-exist"), Fetch)?;         let res: git::remote::fetch::Outcome = remote            .connect(Fetch, git::progress::Discard)?            .prepare_fetch(Default::default())?            .receive(&AtomicBool::default())?;         match res.status {            git::remote::fetch::Status::Change {write_pack_bundle, ..} => {                assert_eq!(write_pack_bundle.index.data_hash, hex_to_id("029d08823bd8a8eab510ad6ac75c823cfd3ed31e"));                assert_eq!(write_pack_bundle.index.num_objects, 0, "empty pack")},            _ => unreachable!("Naive negotiation sends the same have and wants, resulting in an empty pack (technically no change, but we don't detect it) - empty packs are fine")        }        Ok(())    }     #[test]    fn fetch_pack() -> crate::Result {        for (version, expected_objects, expected_hash) in [            (None, 4, "d07c527cf14e524a8494ce6d5d08e28079f5c6ea"),            (                Some(git::protocol::transport::Protocol::V2),                4,                "d07c527cf14e524a8494ce6d5d08e28079f5c6ea",            ),            (                Some(git::protocol::transport::Protocol::V1),                3,                "c75114f60ab2c9389916f3de1082bbaa47491e3b",            ),        ] {            let (mut repo, _tmp) = repo_rw("two-origins");            if let Some(version) = version {                repo.config_snapshot_mut().set_raw_value(                    "protocol",                    None,                    "version",                    (version as u8).to_string().as_str(),                )?;            }             // No updates            {                let remote = repo.find_remote("origin")?;                {                    remote                        .connect(Fetch, progress::Discard)?                        .prepare_fetch(Default::default())?;                    // early drops are fine and won't block.                }                let outcome = remote                    .connect(Fetch, progress::Discard)?                    .prepare_fetch(Default::default())?                    .receive(&AtomicBool::default())?;                assert!(matches!(outcome.status, git::remote::fetch::Status::NoChange));            }             // Some updates to be fetched            for dry_run in [true, false] {                let remote = repo.find_remote("changes-on-top-of-origin")?;                let outcome: git::remote::fetch::Outcome = remote                    .connect(Fetch, progress::Discard)?                    .prepare_fetch(Default::default())?                    .with_dry_run(dry_run)                    .receive(&AtomicBool::default())?;                let refs = match outcome.status {                    fetch::Status::Change {                        write_pack_bundle,                        update_refs,                    } => {                        assert_eq!(write_pack_bundle.pack_version, git::odb::pack::data::Version::V2);                        assert_eq!(write_pack_bundle.object_hash, repo.object_hash());                        assert_eq!(write_pack_bundle.index.num_objects, expected_objects, "this value is 4 when git does it with 'consecutive' negotiation style, but could be 33 if completely naive.");                        assert_eq!(                            write_pack_bundle.index.index_version,                            git::odb::pack::index::Version::V2                        );                        assert_eq!(write_pack_bundle.index.index_hash, hex_to_id(expected_hash));                        assert!(write_pack_bundle.data_path.map_or(false, |f| f.is_file()));                        assert!(write_pack_bundle.index_path.map_or(false, |f| f.is_file()));                         update_refs                    }                    fetch::Status::DryRun { update_refs } => update_refs,                    fetch::Status::NoChange => unreachable!("we firmly expect changes here"),                };                 assert_eq!(                    refs.updates,                    vec![fetch::refs::Update {                        mode: fetch::refs::update::Mode::New,                        edit_index: Some(0),                    }]                );                for (_update, mapping, _spec, edit) in                    refs.iter_mapping_updates(&outcome.ref_map.mappings, remote.refspecs(Fetch))                {                    let edit = edit.expect("refedit present even if it's a no-op");                    if dry_run {                        assert_eq!(                            edit.change.new_value().expect("no deletions").id(),                            mapping.remote.as_id()                        );                        assert!(                            repo.try_find_reference(edit.name.as_ref())?.is_none(),                            "no ref created in dry-run mode"                        );                    } else {                        let r = repo.find_reference(edit.name.as_ref()).unwrap();                        assert_eq!(                            r.id(),                            *mapping.remote.as_id(),                            "local reference should point to remote id"                        );                    }                }            }        }        Ok(())    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t