summaryrefslogtreecommitdiffstats
path: root/vendor/gix/src/repository/submodule.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/gix/src/repository/submodule.rs
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix/src/repository/submodule.rs')
-rw-r--r--vendor/gix/src/repository/submodule.rs96
1 files changed, 96 insertions, 0 deletions
diff --git a/vendor/gix/src/repository/submodule.rs b/vendor/gix/src/repository/submodule.rs
new file mode 100644
index 000000000..a605bfbd3
--- /dev/null
+++ b/vendor/gix/src/repository/submodule.rs
@@ -0,0 +1,96 @@
+use std::rc::Rc;
+
+use crate::{submodule, Repository};
+
+impl Repository {
+ /// Open the `.gitmodules` file as present in the worktree, or return `None` if no such file is available.
+ /// Note that git configuration is also contributing to the result based on the current snapshot.
+ ///
+ /// Note that his method will not look in other places, like the index or the `HEAD` tree.
+ // TODO(submodule): make it use an updated snapshot instead once we have `config()`.
+ pub fn open_modules_file(&self) -> Result<Option<gix_submodule::File>, submodule::open_modules_file::Error> {
+ let path = match self.modules_path() {
+ Some(path) => path,
+ None => return Ok(None),
+ };
+ let buf = match std::fs::read(&path) {
+ Ok(buf) => buf,
+ Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None),
+ Err(err) => return Err(err.into()),
+ };
+
+ Ok(Some(gix_submodule::File::from_bytes(
+ &buf,
+ path,
+ &self.config.resolved,
+ )?))
+ }
+
+ /// Return a shared [`.gitmodules` file](crate::submodule::File) which is updated automatically if the in-memory snapshot
+ /// has become stale as the underlying file on disk has changed. The snapshot based on the file on disk is shared across all
+ /// clones of this repository.
+ ///
+ /// If a file on disk isn't present, we will try to load it from the index, and finally from the current tree.
+ /// In the latter two cases, the result will not be cached in this repository instance as we can't detect freshness anymore,
+ /// so time this method is called a new [modules file](submodule::ModulesSnapshot) will be created.
+ ///
+ /// Note that git configuration is also contributing to the result based on the current snapshot.
+ ///
+ // TODO(submodule): make it use an updated snapshot instead once we have `config()`.
+ pub fn modules(&self) -> Result<Option<submodule::ModulesSnapshot>, submodule::modules::Error> {
+ match self.modules.recent_snapshot(
+ || {
+ self.modules_path()
+ .and_then(|path| path.metadata().and_then(|m| m.modified()).ok())
+ },
+ || self.open_modules_file(),
+ )? {
+ Some(m) => Ok(Some(m)),
+ None => {
+ let id = match self.try_index()?.and_then(|index| {
+ index
+ .entry_by_path(submodule::MODULES_FILE.into())
+ .map(|entry| entry.id)
+ }) {
+ Some(id) => id,
+ None => match self
+ .head_commit()?
+ .tree()?
+ .find_entry(submodule::MODULES_FILE)
+ .map(|entry| entry.inner.oid)
+ {
+ Some(id) => id.to_owned(),
+ None => return Ok(None),
+ },
+ };
+ Ok(Some(gix_features::threading::OwnShared::new(
+ gix_submodule::File::from_bytes(&self.find_object(id)?.data, None, &self.config.resolved)
+ .map_err(submodule::open_modules_file::Error::from)?
+ .into(),
+ )))
+ }
+ }
+ }
+
+ /// Return the list of available submodules, or `None` if there is no submodule configuration.
+ #[doc(alias = "git2")]
+ pub fn submodules(&self) -> Result<Option<impl Iterator<Item = crate::Submodule<'_>>>, submodule::modules::Error> {
+ let modules = match self.modules()? {
+ None => return Ok(None),
+ Some(m) => m,
+ };
+ let shared_state = Rc::new(submodule::SharedState::new(self, modules));
+ Ok(Some(
+ shared_state
+ .modules
+ .names()
+ .map(ToOwned::to_owned)
+ .collect::<Vec<_>>()
+ .into_iter()
+ .map(move |name| crate::Submodule {
+ state: shared_state.clone(),
+ name,
+ }),
+ ))
+ }
+}