gitoxide_core/pack/
multi_index.rs

1use std::{io::BufWriter, path::PathBuf, sync::atomic::AtomicBool};
2
3use anyhow::bail;
4use gix::NestedProgress;
5
6use crate::OutputFormat;
7
8pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3;
9
10pub fn verify(
11    multi_index_path: PathBuf,
12    mut progress: impl NestedProgress + 'static,
13    should_interrupt: &AtomicBool,
14) -> anyhow::Result<()> {
15    gix::odb::pack::multi_index::File::at(multi_index_path)?.verify_integrity_fast(&mut progress, should_interrupt)?;
16    Ok(())
17}
18
19pub fn create(
20    index_paths: Vec<PathBuf>,
21    output_path: PathBuf,
22    mut progress: impl NestedProgress + 'static,
23    should_interrupt: &AtomicBool,
24    object_hash: gix::hash::Kind,
25) -> anyhow::Result<()> {
26    let mut out = BufWriter::new(gix::lock::File::acquire_to_update_resource(
27        output_path,
28        gix::lock::acquire::Fail::Immediately,
29        None,
30    )?);
31    gix::odb::pack::multi_index::File::write_from_index_paths(
32        index_paths,
33        &mut out,
34        &mut progress,
35        should_interrupt,
36        gix::odb::pack::multi_index::write::Options { object_hash },
37    )?;
38    out.into_inner()?.commit()?;
39    Ok(())
40}
41
42#[cfg(feature = "serde")]
43mod info {
44    use std::path::PathBuf;
45
46    #[derive(serde::Serialize)]
47    pub struct Statistics {
48        pub path: PathBuf,
49        pub num_objects: u32,
50        pub index_names: Vec<PathBuf>,
51        pub object_hash: String,
52    }
53}
54
55#[cfg_attr(not(feature = "serde"), allow(unused_variables))]
56pub fn info(
57    multi_index_path: PathBuf,
58    format: OutputFormat,
59    out: impl std::io::Write,
60    mut err: impl std::io::Write,
61) -> anyhow::Result<()> {
62    if format == OutputFormat::Human {
63        writeln!(err, "Defaulting to JSON as human format isn't implemented").ok();
64    }
65    #[cfg(feature = "serde")]
66    {
67        let file = gix::odb::pack::multi_index::File::at(&multi_index_path)?;
68        serde_json::to_writer_pretty(
69            out,
70            &info::Statistics {
71                path: multi_index_path,
72                num_objects: file.num_objects(),
73                index_names: file.index_names().to_vec(),
74                object_hash: file.object_hash().to_string(),
75            },
76        )?;
77    }
78    Ok(())
79}
80
81pub fn entries(multi_index_path: PathBuf, format: OutputFormat, mut out: impl std::io::Write) -> anyhow::Result<()> {
82    if format != OutputFormat::Human {
83        bail!("Only human format is supported right now");
84    }
85    let file = gix::odb::pack::multi_index::File::at(multi_index_path)?;
86    for entry in file.iter() {
87        writeln!(out, "{} {} {}", entry.oid, entry.pack_index, entry.pack_offset)?;
88    }
89    Ok(())
90}