This repository has no description
2.3 kB
71 lines
1use std::path::Path;
2
3use knot_git::Repo;
4
5use crate::MaintError;
6use crate::fsio::{self, MIDX_SIDECAR_PREFIX, PackStem};
7
8pub fn exists(objects_dir: &Path) -> bool {
9 fsio::pack_idx_paths(objects_dir)
10 .iter()
11 .any(|idx| idx.with_extension("bitmap").exists())
12}
13
14pub fn refresh(repo: &Repo, objects_dir: &Path) -> Result<bool, MaintError> {
15 let idxs = fsio::pack_idx_paths(objects_dir);
16 match idxs.as_slice() {
17 [only] => {
18 let wrote = knot_git::write_bitmap(repo, only)
19 .map_err(|error| MaintError::Pack(error.to_string()))?;
20 let stem = PackStem::of(only);
21 prune_sidecars(objects_dir, stem.as_ref());
22 Ok(wrote)
23 }
24 [] => {
25 prune_sidecars(objects_dir, None);
26 Ok(false)
27 }
28 _ => {
29 let wrote = knot_git::write_midx_bitmap(repo)
30 .map_err(|error| MaintError::Pack(error.to_string()))?;
31 let keep = current_midx_stem(objects_dir);
32 prune_sidecars(objects_dir, keep.as_ref());
33 Ok(wrote)
34 }
35 }
36}
37
38fn current_midx_stem(objects_dir: &Path) -> Option<PackStem> {
39 let path = objects_dir.join("pack").join("multi-pack-index");
40 let file =
41 gix_pack::multi_index::File::at(path, Some(crate::midx::MIDX_ALLOC_LIMIT_BYTES)).ok()?;
42 Some(PackStem::midx_sidecar(
43 &file.checksum().to_hex().to_string(),
44 ))
45}
46
47fn prune_sidecars(objects_dir: &Path, keep_stem: Option<&PackStem>) {
48 let pack_dir = objects_dir.join("pack");
49 let Ok(entries) = std::fs::read_dir(&pack_dir) else {
50 return;
51 };
52 entries
53 .filter_map(Result::ok)
54 .map(|entry| entry.path())
55 .filter(|path| is_bitmap_sidecar(path))
56 .filter(|path| PackStem::of(path).as_ref() != keep_stem)
57 .for_each(|path| {
58 let _ = std::fs::remove_file(path);
59 });
60}
61
62fn is_bitmap_sidecar(path: &Path) -> bool {
63 match path.extension().and_then(|ext| ext.to_str()) {
64 Some("bitmap") => true,
65 Some("rev") => path
66 .file_name()
67 .and_then(|name| name.to_str())
68 .is_some_and(|name| name.starts_with(MIDX_SIDECAR_PREFIX)),
69 _ => false,
70 }
71}