gitoxide_core/repository/
fsck.rs

1use anyhow::Context;
2use gix::{objs::Kind, ObjectId};
3
4pub fn function(mut repo: gix::Repository, spec: Option<String>, mut out: impl std::io::Write) -> anyhow::Result<()> {
5    let spec = spec.unwrap_or("HEAD".into());
6
7    repo.object_cache_size_if_unset(4 * 1024 * 1024);
8    // We expect to be finding a bunch of non-existent objects here - never refresh the ODB
9    repo.objects.refresh_never();
10
11    let id = repo
12        .rev_parse_single(spec.as_str())
13        .context("Only single revisions are supported")?;
14    let commits: gix::revision::Walk<'_> = id
15        .object()?
16        .peel_to_kind(gix::object::Kind::Commit)
17        .context("Need committish as starting point")?
18        .id()
19        .ancestors()
20        .all()?;
21
22    let on_missing = |oid: &ObjectId, kind: Kind| {
23        writeln!(out, "{oid}: {kind}").expect("failed to write output");
24    };
25
26    let mut check = gix_fsck::Connectivity::new(&repo.objects, on_missing);
27    // Walk all commits, checking each one for connectivity
28    for commit in commits {
29        let commit = commit?;
30        check.check_commit(&commit.id)?;
31        // Note that we leave parent-iteration to the commits iterator, as it will
32        // correctly handle shallow repositories which are expected to have the commits
33        // along the shallow boundary missing.
34    }
35    Ok(())
36}