summaryrefslogtreecommitdiffstats
path: root/vendor/gix/src/shallow.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix/src/shallow.rs')
-rw-r--r--vendor/gix/src/shallow.rs92
1 files changed, 92 insertions, 0 deletions
diff --git a/vendor/gix/src/shallow.rs b/vendor/gix/src/shallow.rs
new file mode 100644
index 000000000..d49653a65
--- /dev/null
+++ b/vendor/gix/src/shallow.rs
@@ -0,0 +1,92 @@
+pub(crate) type CommitsStorage =
+ gix_features::threading::OwnShared<gix_fs::SharedFileSnapshotMut<Vec<gix_hash::ObjectId>>>;
+/// A lazily loaded and auto-updated list of commits which are at the shallow boundary (behind which there are no commits available),
+/// sorted to allow bisecting.
+pub type Commits = gix_fs::SharedFileSnapshot<Vec<gix_hash::ObjectId>>;
+
+///
+#[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]
+pub mod write {
+ pub(crate) mod function {
+ use std::io::Write;
+
+ use gix_protocol::fetch::response::ShallowUpdate;
+
+ use crate::shallow::{write::Error, Commits};
+
+ /// Write the previously obtained (possibly non-existing) `shallow_commits` to the shallow `file`
+ /// after applying all `updates`.
+ ///
+ /// If this leaves the list of shallow commits empty, the file is removed.
+ ///
+ /// ### Deviation
+ ///
+ /// Git also prunes the set of shallow commits while writing, we don't until we support some sort of pruning.
+ pub fn write(
+ mut file: gix_lock::File,
+ shallow_commits: Option<Commits>,
+ updates: &[ShallowUpdate],
+ ) -> Result<(), Error> {
+ let mut shallow_commits = shallow_commits.map(|sc| (**sc).to_owned()).unwrap_or_default();
+ for update in updates {
+ match update {
+ ShallowUpdate::Shallow(id) => {
+ shallow_commits.push(*id);
+ }
+ ShallowUpdate::Unshallow(id) => shallow_commits.retain(|oid| oid != id),
+ }
+ }
+ if shallow_commits.is_empty() {
+ std::fs::remove_file(file.resource_path())?;
+ drop(file);
+ return Ok(());
+ }
+
+ if shallow_commits.is_empty() {
+ if let Err(err) = std::fs::remove_file(file.resource_path()) {
+ if err.kind() != std::io::ErrorKind::NotFound {
+ return Err(err.into());
+ }
+ }
+ } else {
+ shallow_commits.sort();
+ let mut buf = Vec::<u8>::new();
+ for commit in shallow_commits {
+ commit.write_hex_to(&mut buf).map_err(Error::Io)?;
+ buf.push(b'\n');
+ }
+ file.write_all(&buf).map_err(Error::Io)?;
+ file.flush()?;
+ }
+ file.commit()?;
+ Ok(())
+ }
+ }
+
+ /// The error returned by [`write()`][crate::shallow::write()].
+ #[derive(Debug, thiserror::Error)]
+ #[allow(missing_docs)]
+ pub enum Error {
+ #[error(transparent)]
+ Commit(#[from] gix_lock::commit::Error<gix_lock::File>),
+ #[error("Could not remove an empty shallow file")]
+ RemoveEmpty(#[from] std::io::Error),
+ #[error("Failed to write object id to shallow file")]
+ Io(std::io::Error),
+ }
+}
+#[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]
+pub use write::function::write;
+
+///
+pub mod open {
+ /// The error returned by [`Repository::shallow_commits()`][crate::Repository::shallow_commits()].
+ #[derive(Debug, thiserror::Error)]
+ #[allow(missing_docs)]
+ pub enum Error {
+ #[error("Could not open shallow file for reading")]
+ Io(#[from] std::io::Error),
+ #[error("Could not decode a line in shallow file as hex-encoded object hash")]
+ DecodeHash(#[from] gix_hash::decode::Error),
+ }
+}