cloning from ssh works, rename refs instead of fast forward

This commit is contained in:
Bryson Steck 2025-03-12 21:32:53 -06:00
parent b4c8fbfa6f
commit e3d24c3972
Signed by: bryson
SSH key fingerprint: SHA256:XpKABw/nP4z8UVaH+weLaBnEOD86+cVwif+QjuYLGT4

View file

@ -52,22 +52,48 @@ impl Refractr {
common::verbose(self.verbose, 2, format!("Pulling origin"));
repo.find_remote("origin")?.fetch(&branches, None, None)?;
let fetch_head = repo.find_reference("FETCH_HEAD")?;
let fetch_commit = repo.reference_to_annotated_commit(&fetch_head)?;
let analysis = repo.merge_analysis(&[&fetch_commit])?;
if analysis.0.is_fast_forward() {
for branch in branches {
let refname = format!("refs/remotes/origin/{}", branch);
let mut reference = repo.find_reference(&refname)?;
reference.rename(format!("refs/heads/{}", branch).as_str(), false, "")?;
repo.set_head(&refname)?;
let _ = repo.checkout_head(Some(CheckoutBuilder::default().force()));
}
for branch in branches {
let refname = format!("refs/remotes/origin/{}", branch);
let mut reference = repo.find_reference(&refname)?;
reference.rename(format!("refs/heads/{}", branch).as_str(), true, "")?;
}
Ok(())
}
fn fetch(&self, repo: &Repository, branches: &Vec<String>, ssh: Option<&String>) -> Result<(), Error> {
match ssh {
Some(key) => {
let mut cb = RemoteCallbacks::new();
let mut fo = FetchOptions::new();
cb.credentials(move |_,_,_| Cred::ssh_key(
"git",
None,
Path::new(&key),
None));
cb.certificate_check(|cert, url| {
let mut sha256 = String::new();
for i in cert.as_hostkey().unwrap().hash_sha256().unwrap().to_vec() {
sha256.push_str(&hex::encode(i.to_string()));
}
common::warning(
format!("implicitly trusting unknown host {} with sha256 host key {}",
url,
hex::encode(cert.as_hostkey().unwrap().hash_sha256().unwrap().to_vec())));
common::warning(
format!("to ignore this error in the future, add this host to your known_hosts file"));
Ok(CertificateCheckStatus::CertificateOk)
});
fo.download_tags(git2::AutotagOption::All);
fo.remote_callbacks(cb);
repo.find_remote("origin")?.fetch(&branches, Some(&mut fo), None)?;
},
None => repo.find_remote("origin")?.fetch(&branches, None, None)?
};
Ok(())
}
fn set_up_refs(&self, repo: &Repository, branches: &Vec<String>) -> Result<(), Error> {
for branch in branches {
let mut fetch_head = repo.find_reference(format!("refs/remotes/origin/{}", branch).as_str())?;
@ -192,14 +218,6 @@ impl Refractr {
self.verbose,
2,
format!("Interval for {} has arrived, pulling", repos[i].cfg.from));
let mut origin = repos[i].repo.find_remote("origin").unwrap();
let mut refs = Vec::new();
let strings = self.get_refs(&repos[i].cfg.branches);
for branch in &strings {
refs.push(branch.as_str());
}
origin.fetch(&refs, None, None).unwrap();
self.set_up_refs(&repos[i].repo, &repos[i].cfg.branches);
let _ = self.fast_forward(&repos[i].path, &repos[i].cfg.branches);
if let Err(e) = self.push_remotes(
@ -256,11 +274,33 @@ impl Refractr {
1,
format!("Cloning repository: {}", &cfg.config.from));
let cb = RemoteCallbacks::new();
let mut builder = RepoBuilder::new();
let mut cb = RemoteCallbacks::new();
let mut fo = FetchOptions::new();
if cfg.config.from.starts_with("ssh://") {
let key_string = cfg.config.git.ssh_identity_file.clone();
cb.credentials(move |_,_,_| Cred::ssh_key(
"git",
None,
Path::new(&key_string),
None));
cb.certificate_check(|cert, url| {
let mut sha256 = String::new();
for i in cert.as_hostkey().unwrap().hash_sha256().unwrap().to_vec() {
sha256.push_str(&hex::encode(i.to_string()));
}
common::warning(
format!("implicitly trusting unknown host {} with sha256 host key {}",
url,
hex::encode(cert.as_hostkey().unwrap().hash_sha256().unwrap().to_vec())));
common::warning(
format!("to ignore this error in the future, add this host to your known_hosts file"));
Ok(CertificateCheckStatus::CertificateOk)
});
}
fo.download_tags(git2::AutotagOption::All);
fo.remote_callbacks(cb);
let mut builder = RepoBuilder::new();
builder.fetch_options(fo);
let repo_dir = format!("{}/{}", &path_str, repo_name);
@ -279,17 +319,10 @@ impl Refractr {
}
};
let repo_fresh = Repository::open(Path::new(&repo_dir)).unwrap();
self.set_up_refs(&repo_fresh, &cfg.config.branches);
let mut origin = repo_fresh.find_remote("origin").unwrap();
let mut refs = Vec::new();
let strings = self.get_refs(&cfg.config.branches);
for branch in &strings {
refs.push(branch.as_str());
}
origin.fetch(&refs, None, None).unwrap();
self.set_up_refs(&repo, &cfg.config.branches);
self.fetch(&repo, &cfg.config.branches, Some(&cfg.config.git.ssh_identity_file)).unwrap();
let remotes = match self.make_remotes(&repo_fresh, &cfg) {
let remotes = match self.make_remotes(&repo, &cfg) {
Ok(v) => v,
Err(e) => return Err(e)
};