1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use std::path::PathBuf;
use crate::store_impl::{file, packed};
impl file::Store {
pub(crate) fn packed_transaction(
&self,
lock_mode: gix_lock::acquire::Fail,
) -> Result<packed::Transaction, transaction::Error> {
let lock = gix_lock::File::acquire_to_update_resource(self.packed_refs_path(), lock_mode, None)?;
Ok(packed::Transaction::new_from_pack_and_lock(
self.assure_packed_refs_uptodate()?,
lock,
))
}
pub fn open_packed_buffer(&self) -> Result<Option<packed::Buffer>, packed::buffer::open::Error> {
let need_more_than_this_many_bytes_to_use_mmap = 32 * 1024;
match packed::Buffer::open(self.packed_refs_path(), need_more_than_this_many_bytes_to_use_mmap) {
Ok(buf) => Ok(Some(buf)),
Err(packed::buffer::open::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => Ok(None),
Err(err) => Err(err),
}
}
pub fn cached_packed_buffer(
&self,
) -> Result<Option<file::packed::SharedBufferSnapshot>, packed::buffer::open::Error> {
self.assure_packed_refs_uptodate()
}
pub fn packed_refs_path(&self) -> PathBuf {
self.common_dir_resolved().join("packed-refs")
}
pub(crate) fn packed_refs_lock_path(&self) -> PathBuf {
let mut p = self.packed_refs_path();
p.set_extension("lock");
p
}
}
pub mod transaction {
use crate::store_impl::packed;
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error("An existing pack couldn't be opened or read when preparing a transaction")]
BufferOpen(#[from] packed::buffer::open::Error),
#[error("The lock for a packed transaction could not be obtained")]
TransactionLock(#[from] gix_lock::acquire::Error),
}
}
pub type SharedBufferSnapshot = gix_features::fs::SharedSnapshot<packed::Buffer>;
pub(crate) mod modifiable {
use gix_features::threading::OwnShared;
use crate::{file, packed};
pub(crate) type MutableSharedBuffer = OwnShared<gix_features::fs::MutableSnapshot<packed::Buffer>>;
impl file::Store {
pub(crate) fn force_refresh_packed_buffer(&self) -> Result<(), packed::buffer::open::Error> {
self.packed.force_refresh(|| {
let modified = self.packed_refs_path().metadata()?.modified()?;
self.open_packed_buffer().map(|packed| Some(modified).zip(packed))
})
}
pub(crate) fn assure_packed_refs_uptodate(
&self,
) -> Result<Option<super::SharedBufferSnapshot>, packed::buffer::open::Error> {
self.packed.recent_snapshot(
|| self.packed_refs_path().metadata().and_then(|m| m.modified()).ok(),
|| self.open_packed_buffer(),
)
}
}
}