Move towards having GitBackend split into files
parent: tbd commit: e55da0e
1 | use ; |
2 | |
3 | use Error; |
4 | use |
5 | , | Object
6 | |
7 | Commit, DefaultBranch, Repository, RepositoryFile, RepositoryFileFromIdRequest, |
8 | RepositoryFileFromPathRequest, RepositoryFileInspectRequest, |
9 | RepositoryLastCommitOfFileRequest, RepositoryObjectType, RepositoryTreeEntry, |
10 | , |
11 | ; |
12 | use ; |
13 | |
14 | use crate GitBackendError; |
15 | |
16 | use GitBackend; |
17 | |
18 | |
19 | // TODO: Cache this and general repository tree and invalidate select files on push |
20 | // TODO: Find better and faster technique for this |
21 | /// Gets the last commit made to a file by revwalking starting at the passed commit and sorting by time |
22 | |
23 | path: &str, |
24 | git: & Repository, |
25 | start_commit: & Commit, |
26 | |
27 | trace!; |
28 | |
29 | let mut revwalk = git.revwalk?; |
30 | revwalk.set_sorting?; |
31 | revwalk.push?; |
32 | |
33 | for oid in revwalk |
34 | let oid = oid?; |
35 | let commit = git.find_commit?; |
36 | |
37 | // Merge commits have 2 or more parents |
38 | // Commits with 0 parents are handled different because we can't diff against them |
39 | if commit.parent_count == 0 |
40 | return Ok; |
41 | else if commit.parent_count == 1 |
42 | let tree = commit.tree?; |
43 | let last_tree = commit.parent?.tree?; |
44 | |
45 | // Get the diff between the current tree and the last one |
46 | let diff = git.diff_tree_to_tree?; |
47 | |
48 | for dd in diff.deltas |
49 | // Get the path of the current file we're diffing against |
50 | let current_path = dd.new_file .path .unwrap; |
51 | |
52 | // Path or directory |
53 | if current_path.eq || current_path.starts_with |
54 | return Ok; |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | Err? |
61 | |
62 | |
63 | /// If the OID can't be found because there's no repository head, this will return an empty `Vec`. |
64 | pub async |
65 | &mut self, |
66 | requester: & , |
67 | repository_object: &mut , |
68 | OperationState | : ,
69 | request: &RepositoryFileInspectRequest, |
70 | |
71 | let repository = repository_object.object; |
72 | let git = self |
73 | .open_repository_and_check_permissions |
74 | .await?; |
75 | |
76 | let default_branch = repository_object |
77 | . |
78 | .await?; |
79 | // Try and find the tree_id/branch |
80 | let tree_id = |
81 | match Self get_oid_from_reference |
82 | Ok => oid, |
83 | Err => return Ok, |
84 | Err => return Err, |
85 | ; |
86 | |
87 | // Get the commit from the oid |
88 | let commit = match git.find_commit |
89 | Ok => commit, |
90 | // If the commit isn't found, it's generally safe to assume the tree is empty. |
91 | Err => return Ok, |
92 | ; |
93 | |
94 | // this is stupid |
95 | let rev = request.rev.clone .unwrap_or_else; |
96 | let mut current_path = rev.clone; |
97 | |
98 | // Get the commit tree |
99 | let git_tree = if let Some = &request.path |
100 | // Add it to our full path string |
101 | current_path.push_str; |
102 | // Get the specified path, return an error if it wasn't found. |
103 | let entry = match commit |
104 | .tree |
105 | .unwrap |
106 | .get_path |
107 | .map_err |
108 | |
109 | Ok => entry, |
110 | Err => return Err, |
111 | ; |
112 | // Turn the entry into a git tree |
113 | entry.to_object .unwrap .as_tree .unwrap .clone |
114 | else |
115 | commit.tree .unwrap |
116 | ; |
117 | |
118 | // Iterate over the git tree and collect it into our own tree types |
119 | let mut tree = git_tree |
120 | .iter |
121 | .map |
122 | let object_type = match entry.kind .unwrap |
123 | => Tree, | Tree
124 | => Blob, | Blob
125 | _ => unreachable!, |
126 | ; |
127 | let mut tree_entry = new |
128 | entry.id .to_string .as_str, |
129 | entry.name .unwrap, |
130 | object_type, |
131 | entry.filemode, |
132 | ; |
133 | |
134 | if request.extra_metadata |
135 | // Get the file size if It's a blob |
136 | let object = entry.to_object .unwrap; |
137 | if let Some = object.as_blob |
138 | tree_entry.size = Some; |
139 | |
140 | |
141 | // Get the path to the folder the file is in by removing the rev from current_path |
142 | let mut path = current_path.replace; |
143 | if path.starts_with |
144 | path.remove; |
145 | |
146 | |
147 | // Format it as the path + file name |
148 | let full_path = if path.is_empty |
149 | entry.name .unwrap .to_string |
150 | else |
151 | format! |
152 | ; |
153 | |
154 | // Get the last commit made to the entry |
155 | if let Ok = |
156 | get_last_commit_of_file |
157 | |
158 | tree_entry.last_commit = Some; |
159 | |
160 | |
161 | |
162 | tree_entry |
163 | |
164 | .; |
165 | |
166 | // Sort the tree alphabetically and with tree first |
167 | tree.sort_unstable_by_key; |
168 | tree.sort_unstable_by_key |
169 | Reverse |
170 | ; |
171 | |
172 | Ok |
173 | |
174 | |
175 | pub async |
176 | &mut self, |
177 | requester: & , |
178 | repository_object: &mut , |
179 | OperationState | : ,
180 | request: &RepositoryFileFromIdRequest, |
181 | |
182 | let repository = repository_object.object; |
183 | let git = self |
184 | .open_repository_and_check_permissions |
185 | .await?; |
186 | |
187 | // Parse the passed object id |
188 | let oid = match from_str |
189 | Ok => oid, |
190 | Err => |
191 | return Err |
192 | |
193 | ; |
194 | |
195 | // Find the file and turn it into our own struct |
196 | let file = match git.find_blob |
197 | Ok => RepositoryFile |
198 | id: blob.id .to_string, |
199 | content: blob.content .to_vec, |
200 | binary: blob.is_binary, |
201 | size: blob.size, |
202 | , |
203 | Err => return Err, |
204 | ; |
205 | |
206 | Ok |
207 | |
208 | |
209 | pub async |
210 | &mut self, |
211 | requester: & , |
212 | repository_object: &mut , |
213 | OperationState | : ,
214 | request: &RepositoryFileFromPathRequest, |
215 | |
216 | let repository = repository_object.object; |
217 | let git = self |
218 | .open_repository_and_check_permissions |
219 | .await?; |
220 | |
221 | let default_branch = repository_object |
222 | . |
223 | .await?; |
224 | let tree_id = Self get_oid_from_reference?; |
225 | |
226 | // unwrap might be dangerous? |
227 | // Get the commit from the oid |
228 | let commit = git.find_commit .unwrap; |
229 | |
230 | // this is stupid |
231 | let mut current_path = request.rev.clone .unwrap_or_else; |
232 | |
233 | // Add it to our full path string |
234 | current_path.push_str; |
235 | // Get the specified path, return an error if it wasn't found. |
236 | let entry = match commit |
237 | .tree |
238 | .unwrap |
239 | .get_path |
240 | .map_err |
241 | |
242 | Ok => entry, |
243 | Err => return Err, |
244 | ; |
245 | |
246 | // Find the file and turn it into our own struct |
247 | let file = match git.find_blob |
248 | Ok => RepositoryFile |
249 | id: blob.id .to_string, |
250 | content: blob.content .to_vec, |
251 | binary: blob.is_binary, |
252 | size: blob.size, |
253 | , |
254 | Err => |
255 | return Err |
256 | |
257 | ; |
258 | |
259 | Ok |
260 | |
261 | |
262 | pub async |
263 | &mut self, |
264 | requester: & , |
265 | repository_object: &mut , |
266 | OperationState | : ,
267 | request: &RepositoryLastCommitOfFileRequest, |
268 | |
269 | let repository = repository_object.object; |
270 | let git = self |
271 | .open_repository_and_check_permissions |
272 | .await?; |
273 | |
274 | // Parse the passed object ids |
275 | let oid = from_str |
276 | .map_err?; |
277 | |
278 | // Get the commit from the oid |
279 | let commit = git |
280 | .find_commit |
281 | .map_err?; |
282 | |
283 | // Find the last commit of the file |
284 | let commit = get_last_commit_of_file?; |
285 | |
286 | Ok |
287 | |
288 | |
289 |