Skip to main content

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