This commit is contained in:
2026-10-13 10:27:27 +07:00
parent f02f699ace
commit 3c307691aa
3 changed files with 48 additions and 117 deletions
+1 -50
View File
@@ -1,4 +1,4 @@
use std::collections::{BTreeSet, HashMap, HashSet};
use std::collections::{BTreeSet, HashSet};
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::Stdio;
@@ -1262,55 +1262,6 @@ impl Repo {
Ok(())
}
/// Checks that `url` advertises exactly the expected ref oids.
pub fn remote_has_refs(&self, url: &str, expected: &[(String, String)]) -> Result<bool> {
if expected.is_empty() {
return Ok(true);
}
let url = Self::transport_url(url);
let refspecs = expected
.iter()
.map(|(name, _)| {
gix::refspec::parse(
gix::bstr::BStr::new(format!("+{name}:{name}").as_bytes()),
gix::refspec::parse::Operation::Fetch,
)
.map(|spec| spec.to_owned())
})
.collect::<Result<Vec<_>, _>>()
.into_anyhow()
.context("invalid refspec")?;
let options = gix::remote::ref_map::Options {
extra_refspecs: refspecs,
..Default::default()
};
let (refs, _) = self
.inner
.remote_at(url.as_str())
.with_context(|| format!("cannot use remote {url}"))?
.connect(gix::remote::Direction::Fetch)
.with_context(|| format!("cannot connect to {url}"))?
.ref_map(Discard, options)
.with_context(|| format!("listing refs of {url} failed"))?;
let advertised: HashMap<String, String> = refs
.remote_refs
.iter()
.filter_map(|reference| {
let (name, object, _peeled) = reference.unpack();
object.map(|oid| (String::from_utf8_lossy(name).into_owned(), oid.to_string()))
})
.collect();
Ok(expected
.iter()
.all(|(name, oid)| advertised.get(name.as_str()) == Some(oid)))
}
/// Sets the `origin` URL when the repository has no remote yet.
pub fn ensure_origin(&self, url: &str) -> Result<()> {
if self.inner.find_remote("origin").is_ok() {
-36
View File
@@ -113,42 +113,6 @@ fn ref_state_matches_the_git_cli_ref_listing() {
);
}
#[test]
fn remote_has_refs_reports_whether_pushed_refs_landed() {
let server = tempfile::tempdir().unwrap();
bare_server(server.path(), "npub1test", "my-repo");
let (dir, repo) = fixture(&[("a.txt", b"one")]);
commit_all(&repo, "initial");
let dir = dir.path();
let main = git_in(dir, &["rev-parse", "refs/heads/main"]).expect("main oid");
let url = format!("file://{}/npub1test/my-repo.git", server.path().display());
let expected = vec![("refs/heads/main".to_owned(), main.clone())];
let repo = Repo::open(dir).expect("open");
assert!(!repo.remote_has_refs(&url, &expected).expect("probe"));
repo.push_all(
&format!("file://{}", server.path().display()),
"npub1test",
"my-repo",
)
.expect("push");
assert!(repo.remote_has_refs(&url, &expected).expect("probe"));
let stale = vec![("refs/heads/main".to_owned(), "0".repeat(40))];
assert!(!repo.remote_has_refs(&url, &stale).expect("probe"));
git_run(dir, &["tag", "v1.0"]);
repo.push_all(
&format!("file://{}", server.path().display()),
"npub1test",
"my-repo",
)
.expect("push");
assert!(repo.remote_has_refs(&url, &expected).expect("probe"));
}
#[test]
fn repo_ref_state_lists_branches_tags_and_head() {
let (_dir, repo) = fixture(&[("a.txt", b"hello")]);