use crate::object::Object;
use crate::utils::as_hex;
use crate::{Error, Execute as _, Fetch, WithError as _, bail};
use super::Repo;
impl Repo {
pub fn fetch_blobs(&self, oid: &str, blobs: Vec<String>) -> Result<Vec<Object>, Error> {
let cmd = Fetch {
want: blobs,
have: vec![oid.to_owned()],
filter: Some("object:type=blob".to_owned()),
deepen: None,
hash_kind: self.hash_kind,
include_tag: false,
};
let packfile = cmd.execute(self)?;
packfile.collect::<Result<_, _>>()
}
pub fn fetch_tree(&self, have: &str, want: &str, blobs: bool) -> Result<Vec<Object>, Error> {
let cmd = Fetch {
want: vec![want.to_owned()],
have: vec![have.to_owned()],
filter: if blobs {
None
} else {
Some("blob:none".to_owned())
},
deepen: None,
hash_kind: self.hash_kind,
include_tag: false,
};
let packfile = cmd.execute(self)?;
packfile.collect::<Result<_, _>>()
}
pub fn fetch_history_linear(
&mut self,
start: &str,
end: &str,
blobs: bool,
) -> Result<Vec<String>, Error> {
let cmd = Fetch {
want: vec![end.to_owned()],
have: vec![start.to_owned()],
filter: if blobs {
None
} else {
Some("blob:none".to_owned())
},
deepen: None,
hash_kind: self.hash_kind,
include_tag: false,
};
let packfile = cmd.execute(self)?;
for obj in packfile {
let obj = obj.with_err_msg("could not get object")?;
let hash = as_hex(obj.hash().as_ref());
self.object_cache.insert(hash, obj);
}
let mut new_head = end.to_owned();
let mut commits = vec![];
loop {
let Some(Object::Commit(commit)) = self.object_cache.get(&new_head) else {
bail!("commit not found: {new_head}");
};
let parents = &commit.parents;
if parents.len() > 1 {
bail!("commit history non-linear");
}
if new_head == start {
break;
}
commits.push(new_head);
new_head = parents.first().with_err_msg("no parent")?.to_string();
}
Ok(commits)
}
pub fn fetch_shallow(&mut self, oid: &str) -> Result<(), Error> {
let cmd = Fetch {
want: vec![oid.to_owned()],
have: vec![],
filter: Some("blob:none".to_owned()),
deepen: Some(1),
hash_kind: self.hash_kind,
include_tag: false,
};
let packfile = cmd.execute(self)?;
for obj in packfile {
let obj = obj.with_err_msg("could not get object")?;
let hash = as_hex(obj.hash().as_ref());
self.object_cache.insert(hash, obj);
}
Ok(())
}
}