1use crate::object::Object;
2use crate::utils::as_hex;
3use crate::{Error, Execute as _, Fetch, WithError as _, bail};
4
5use super::Repo;
6
7impl Repo {
8 pub fn fetch_blobs(&self, oid: &str, blobs: Vec<String>) -> Result<Vec<Object>, Error> {
14 let cmd = Fetch {
15 want: blobs,
16 have: vec![oid.to_owned()],
17 filter: Some("object:type=blob".to_owned()),
18 deepen: None,
19 hash_kind: self.hash_kind,
20 include_tag: false,
21 };
22
23 let packfile = cmd.execute(self)?;
24
25 packfile.collect::<Result<_, _>>()
26 }
27
28 pub fn fetch_tree(&self, have: &str, want: &str, blobs: bool) -> Result<Vec<Object>, Error> {
34 let cmd = Fetch {
35 want: vec![want.to_owned()],
36 have: vec![have.to_owned()],
37 filter: if blobs {
38 None
39 } else {
40 Some("blob:none".to_owned())
41 },
42 deepen: None,
43 hash_kind: self.hash_kind,
44 include_tag: false,
45 };
46
47 let packfile = cmd.execute(self)?;
48
49 packfile.collect::<Result<_, _>>()
50 }
51
52 pub fn fetch_history_linear(
59 &mut self,
60 start: &str,
61 end: &str,
62 blobs: bool,
63 ) -> Result<Vec<String>, Error> {
64 let cmd = Fetch {
65 want: vec![end.to_owned()],
66 have: vec![start.to_owned()],
67 filter: if blobs {
68 None
69 } else {
70 Some("blob:none".to_owned())
71 },
72 deepen: None,
73 hash_kind: self.hash_kind,
74 include_tag: false,
75 };
76
77 let packfile = cmd.execute(self)?;
78
79 for obj in packfile {
80 let obj = obj.with_err_msg("could not get object")?;
81 let hash = as_hex(obj.hash().as_ref());
82
83 self.object_cache.insert(hash, obj);
84 }
85
86 let mut new_head = end.to_owned();
87 let mut commits = vec![];
88
89 loop {
90 let Some(Object::Commit(commit)) = self.object_cache.get(&new_head) else {
91 bail!("commit not found: {new_head}");
92 };
93
94 let parents = &commit.parents;
95 if parents.len() > 1 {
96 bail!("commit history non-linear");
97 }
98
99 if new_head == start {
100 break;
101 }
102 commits.push(new_head);
103
104 new_head = parents.first().with_err_msg("no parent")?.to_string();
105 }
106
107 Ok(commits)
108 }
109
110 pub fn fetch_shallow(&mut self, oid: &str) -> Result<(), Error> {
116 let cmd = Fetch {
117 want: vec![oid.to_owned()],
118 have: vec![],
119 filter: Some("blob:none".to_owned()),
120 deepen: Some(1),
121 hash_kind: self.hash_kind,
122 include_tag: false,
123 };
124
125 let packfile = cmd.execute(self)?;
126
127 for obj in packfile {
128 let obj = obj.with_err_msg("could not get object")?;
129 let hash = as_hex(obj.hash().as_ref());
130
131 self.object_cache.insert(hash, obj);
132 }
133
134 Ok(())
135 }
136}