summaryrefslogtreecommitdiffstats
path: root/vendor/gix-odb/src/store_impls/loose/write.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-odb/src/store_impls/loose/write.rs')
-rw-r--r--vendor/gix-odb/src/store_impls/loose/write.rs41
1 files changed, 40 insertions, 1 deletions
diff --git a/vendor/gix-odb/src/store_impls/loose/write.rs b/vendor/gix-odb/src/store_impls/loose/write.rs
index e87462e4c..912426bba 100644
--- a/vendor/gix-odb/src/store_impls/loose/write.rs
+++ b/vendor/gix-odb/src/store_impls/loose/write.rs
@@ -98,6 +98,16 @@ impl crate::traits::Write for Store {
type CompressedTempfile = deflate::Write<NamedTempFile>;
+/// Access
+impl Store {
+ /// Return the path to the object with `id`.
+ ///
+ /// Note that is may not exist yet.
+ pub fn object_path(&self, id: &gix_hash::oid) -> PathBuf {
+ loose::hash_path(id, self.path.clone())
+ }
+}
+
impl Store {
fn dest(&self) -> Result<hash::Write<CompressedTempfile>, Error> {
Ok(hash::Write::new(
@@ -126,7 +136,36 @@ impl Store {
}
}
let file = file.into_inner();
- file.persist(&object_path).map_err(|err| Error::Persist {
+ let res = file.persist(&object_path);
+ // On windows, we assume that such errors are due to its special filesystem semantics,
+ // on any other platform that would be a legitimate error though.
+ #[cfg(windows)]
+ if let Err(err) = &res {
+ if err.error.kind() == std::io::ErrorKind::PermissionDenied
+ || err.error.kind() == std::io::ErrorKind::AlreadyExists
+ {
+ return Ok(id);
+ }
+ }
+ #[cfg(unix)]
+ if let Ok(mut perm) = object_path.metadata().map(|m| m.permissions()) {
+ use std::os::unix::fs::PermissionsExt;
+ /// For now we assume the default with standard umask. This can be more sophisticated,
+ /// but we have the bare minimum.
+ fn comp_mode(_mode: u32) -> u32 {
+ 0o444
+ }
+ let new_mode = comp_mode(perm.mode());
+ if (perm.mode() ^ new_mode) & !0o170000 != 0 {
+ perm.set_mode(new_mode);
+ std::fs::set_permissions(&object_path, perm).map_err(|err| Error::Io {
+ source: err,
+ message: "Failed to set permission bits",
+ path: object_path.clone(),
+ })?;
+ }
+ }
+ res.map_err(|err| Error::Persist {
source: err,
target: object_path,
})?;