Skip to content

Commit 5ef8ae8

Browse files
committed
fix!: make topo-traversal resilient against broken parent-id queries.
That way, commiit-graph related errors won't be propagated.
1 parent c515edd commit 5ef8ae8

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

gix-traverse/src/commit/topo/iter.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ where
180180

181181
fn collect_parents(&mut self, id: &oid) -> Result<SmallVec<[(ObjectId, GenAndCommitTime); 1]>, Error> {
182182
collect_parents(
183-
self.commit_graph.as_ref(),
183+
&mut self.commit_graph,
184184
&self.find,
185185
id,
186186
matches!(self.parents, Parents::First),
@@ -193,7 +193,7 @@ where
193193
&mut self,
194194
id: &oid,
195195
) -> Result<SmallVec<[(ObjectId, GenAndCommitTime); 1]>, Error> {
196-
collect_parents(self.commit_graph.as_ref(), &self.find, id, false, &mut self.buf)
196+
collect_parents(&mut self.commit_graph, &self.find, id, false, &mut self.buf)
197197
}
198198

199199
fn pop_commit(&mut self) -> Option<Result<Info, Error>> {
@@ -236,7 +236,7 @@ where
236236
}
237237

238238
fn collect_parents<Find>(
239-
cache: Option<&gix_commitgraph::Graph>,
239+
cache: &mut Option<gix_commitgraph::Graph>,
240240
f: Find,
241241
id: &oid,
242242
first_only: bool,
@@ -246,7 +246,7 @@ where
246246
Find: gix_object::Find,
247247
{
248248
let mut parents = SmallVec::<[(ObjectId, GenAndCommitTime); 1]>::new();
249-
match find(cache, &f, id, buf)? {
249+
match find(cache.as_ref(), &f, id, buf)? {
250250
Either::CommitRefIter(c) => {
251251
for token in c {
252252
use gix_object::commit::ref_iter::Token as T;
@@ -265,15 +265,21 @@ where
265265
// Need to check the cache again. That a commit is not in the cache
266266
// doesn't mean a parent is not.
267267
for (id, gen_time) in parents.iter_mut() {
268-
let commit = find(cache, &f, id, buf)?;
268+
let commit = find(cache.as_ref(), &f, id, buf)?;
269269
*gen_time = gen_and_commit_time(commit)?;
270270
}
271271
}
272272
Either::CachedCommit(c) => {
273273
for pos in c.iter_parents() {
274+
let Ok(pos) = pos else {
275+
// drop corrupt cache and use ODB from now on.
276+
*cache = None;
277+
return collect_parents(cache, f, id, first_only, buf);
278+
};
274279
let parent_commit = cache
280+
.as_ref()
275281
.expect("cache exists if CachedCommit was returned")
276-
.commit_at(pos?);
282+
.commit_at(pos);
277283
parents.push((
278284
parent_commit.id().into(),
279285
(parent_commit.generation(), parent_commit.committer_timestamp() as i64),

gix-traverse/src/commit/topo/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ pub enum Error {
1111
#[error("Internal state (bitflags) not found")]
1212
MissingStateUnexpected,
1313
#[error(transparent)]
14-
CommitGraphFile(#[from] gix_commitgraph::file::commit::Error),
15-
#[error(transparent)]
1614
ObjectDecode(#[from] gix_object::decode::Error),
1715
#[error(transparent)]
1816
Find(#[from] gix_object::find::existing_iter::Error),

0 commit comments

Comments
 (0)