index: propagate store error from reindexing function

If the error is permanent (because the repo predates the no-gc-ref fix for
example), there's no easy way to recover. Still, panicking in this function
seems wrong.
This commit is contained in:
Yuya Nishihara 2023-12-21 09:38:16 +09:00
parent 1836a105bb
commit 0f6a7418f2

View file

@ -26,7 +26,7 @@ use thiserror::Error;
use super::mutable::DefaultMutableIndex; use super::mutable::DefaultMutableIndex;
use super::readonly::{DefaultReadonlyIndex, ReadonlyIndexLoadError, ReadonlyIndexSegment}; use super::readonly::{DefaultReadonlyIndex, ReadonlyIndexLoadError, ReadonlyIndexSegment};
use crate::backend::{CommitId, ObjectId}; use crate::backend::{BackendError, CommitId, ObjectId};
use crate::commit::CommitByCommitterTimestamp; use crate::commit::CommitByCommitterTimestamp;
use crate::dag_walk; use crate::dag_walk;
use crate::file_util::persist_content_addressed_temp_file; use crate::file_util::persist_content_addressed_temp_file;
@ -50,6 +50,8 @@ pub enum DefaultIndexStoreError {
LoadIndex(ReadonlyIndexLoadError), LoadIndex(ReadonlyIndexLoadError),
#[error("Failed to write commit index file: {0}")] #[error("Failed to write commit index file: {0}")]
SaveIndex(#[source] io::Error), SaveIndex(#[source] io::Error),
#[error("Failed to index commits: {0}")]
IndexCommits(#[source] BackendError),
#[error(transparent)] #[error(transparent)]
OpStore(#[from] OpStoreError), OpStore(#[from] OpStoreError),
} }
@ -159,21 +161,22 @@ impl DefaultIndexStore {
.as_ref() .as_ref()
.map_or(false, |segment| segment.as_composite().has_id(id)) .map_or(false, |segment| segment.as_composite().has_id(id))
}; };
let commits = dag_walk::topo_order_reverse_ord( let commits = dag_walk::topo_order_reverse_ord_ok(
new_heads new_heads
.iter() .iter()
.filter(|&id| !parent_file_has_id(id)) .filter(|&id| !parent_file_has_id(id))
.map(|id| store.get_commit(id).unwrap()) .map(|id| store.get_commit(id))
.map(CommitByCommitterTimestamp), .map_ok(CommitByCommitterTimestamp),
|CommitByCommitterTimestamp(commit)| commit.id().clone(), |CommitByCommitterTimestamp(commit)| commit.id().clone(),
|CommitByCommitterTimestamp(commit)| { |CommitByCommitterTimestamp(commit)| {
itertools::chain(commit.parent_ids(), commit.predecessor_ids()) itertools::chain(commit.parent_ids(), commit.predecessor_ids())
.filter(|&id| !parent_file_has_id(id)) .filter(|&id| !parent_file_has_id(id))
.map(|id| store.get_commit(id).unwrap()) .map(|id| store.get_commit(id))
.map(CommitByCommitterTimestamp) .map_ok(CommitByCommitterTimestamp)
.collect_vec() .collect_vec()
}, },
); )
.map_err(DefaultIndexStoreError::IndexCommits)?;
for CommitByCommitterTimestamp(commit) in commits.iter().rev() { for CommitByCommitterTimestamp(commit) in commits.iter().rev() {
mutable_index.add_commit(commit); mutable_index.add_commit(commit);
} }