summaryrefslogtreecommitdiffstats
path: root/vendor/gix/src/repository/snapshots.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix/src/repository/snapshots.rs')
-rw-r--r--vendor/gix/src/repository/snapshots.rs109
1 files changed, 109 insertions, 0 deletions
diff --git a/vendor/gix/src/repository/snapshots.rs b/vendor/gix/src/repository/snapshots.rs
new file mode 100644
index 000000000..6933dc9c6
--- /dev/null
+++ b/vendor/gix/src/repository/snapshots.rs
@@ -0,0 +1,109 @@
+impl crate::Repository {
+ // TODO: tests
+ /// Similar to [`open_mailmap_into()`][crate::Repository::open_mailmap_into()], but ignores all errors and returns at worst
+ /// an empty mailmap, e.g. if there is no mailmap or if there were errors loading them.
+ ///
+ /// This represents typical usage within git, which also works with what's there without considering a populated mailmap
+ /// a reason to abort an operation, considering it optional.
+ pub fn open_mailmap(&self) -> gix_mailmap::Snapshot {
+ let mut out = gix_mailmap::Snapshot::default();
+ self.open_mailmap_into(&mut out).ok();
+ out
+ }
+
+ // TODO: tests
+ /// Try to merge mailmaps from the following locations into `target`:
+ ///
+ /// - read the `.mailmap` file without following symlinks from the working tree, if present
+ /// - OR read `HEAD:.mailmap` if this repository is bare (i.e. has no working tree), if the `mailmap.blob` is not set.
+ /// - read the mailmap as configured in `mailmap.blob`, if set.
+ /// - read the file as configured by `mailmap.file`, following symlinks, if set.
+ ///
+ /// Only the first error will be reported, and as many source mailmaps will be merged into `target` as possible.
+ /// Parsing errors will be ignored.
+ pub fn open_mailmap_into(&self, target: &mut gix_mailmap::Snapshot) -> Result<(), crate::mailmap::load::Error> {
+ let mut err = None::<crate::mailmap::load::Error>;
+ let mut buf = Vec::new();
+ let mut blob_id = self
+ .config
+ .resolved
+ .raw_value("mailmap", None, "blob")
+ .ok()
+ .and_then(|spec| {
+ // TODO: actually resolve this as spec (once we can do that)
+ gix_hash::ObjectId::from_hex(spec.as_ref())
+ .map_err(|e| err.get_or_insert(e.into()))
+ .ok()
+ });
+ match self.work_dir() {
+ None => {
+ // TODO: replace with ref-spec `HEAD:.mailmap` for less verbose way of getting the blob id
+ blob_id = blob_id.or_else(|| {
+ self.head().ok().and_then(|mut head| {
+ let commit = head.peel_to_commit_in_place().ok()?;
+ let tree = commit.tree().ok()?;
+ tree.lookup_entry(Some(".mailmap")).ok()?.map(|e| e.object_id())
+ })
+ });
+ }
+ Some(root) => {
+ if let Ok(mut file) = gix_features::fs::open_options_no_follow()
+ .read(true)
+ .open(root.join(".mailmap"))
+ .map_err(|e| {
+ if e.kind() != std::io::ErrorKind::NotFound {
+ err.get_or_insert(e.into());
+ }
+ })
+ {
+ buf.clear();
+ std::io::copy(&mut file, &mut buf)
+ .map_err(|e| err.get_or_insert(e.into()))
+ .ok();
+ target.merge(gix_mailmap::parse_ignore_errors(&buf));
+ }
+ }
+ }
+
+ if let Some(blob) = blob_id.and_then(|id| self.find_object(id).map_err(|e| err.get_or_insert(e.into())).ok()) {
+ target.merge(gix_mailmap::parse_ignore_errors(&blob.data));
+ }
+
+ let configured_path = self
+ .config
+ .resolved
+ .value::<gix_config::Path<'_>>("mailmap", None, "file")
+ .ok()
+ .and_then(|path| {
+ let install_dir = self.install_dir().ok()?;
+ let home = self.config.home_dir();
+ match path.interpolate(gix_config::path::interpolate::Context {
+ git_install_dir: Some(install_dir.as_path()),
+ home_dir: home.as_deref(),
+ home_for_user: if self.options.git_dir_trust.expect("trust is set") == gix_sec::Trust::Full {
+ Some(gix_config::path::interpolate::home_for_user)
+ } else {
+ None
+ },
+ }) {
+ Ok(path) => Some(path),
+ Err(e) => {
+ err.get_or_insert(e.into());
+ None
+ }
+ }
+ });
+
+ if let Some(mut file) =
+ configured_path.and_then(|path| std::fs::File::open(path).map_err(|e| err.get_or_insert(e.into())).ok())
+ {
+ buf.clear();
+ std::io::copy(&mut file, &mut buf)
+ .map_err(|e| err.get_or_insert(e.into()))
+ .ok();
+ target.merge(gix_mailmap::parse_ignore_errors(&buf));
+ }
+
+ err.map(Err).unwrap_or(Ok(()))
+ }
+}