Function git_discover::is_submodule_git_dir
source · Expand description
Returns true if git_dir
is is located within a .git/modules
directory, indicating it’s a submodule clone.
Examples found in repository?
src/is.rs (line 144)
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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
pub fn git(git_dir: impl AsRef<Path>) -> Result<crate::repository::Kind, crate::is_git::Error> {
#[derive(Eq, PartialEq)]
enum Kind {
MaybeRepo,
Submodule,
LinkedWorkTreeDir,
WorkTreeGitDir { work_dir: std::path::PathBuf },
}
let git_dir = git_dir.as_ref();
let (dot_git, common_dir, kind) = if git_dir
.metadata()
.map_err(|err| crate::is_git::Error::Metadata {
source: err,
path: git_dir.into(),
})?
.is_file()
{
let private_git_dir = crate::path::from_gitdir_file(git_dir)?;
let common_dir = private_git_dir.join("commondir");
match crate::path::from_plain_file(&common_dir) {
Some(Err(err)) => {
return Err(crate::is_git::Error::MissingCommonDir {
missing: common_dir,
source: err,
})
}
Some(Ok(common_dir)) => {
let common_dir = private_git_dir.join(common_dir);
(
Cow::Owned(private_git_dir),
Cow::Owned(common_dir),
Kind::LinkedWorkTreeDir,
)
}
None => (
Cow::Owned(private_git_dir.clone()),
Cow::Owned(private_git_dir),
Kind::Submodule,
),
}
} else {
let common_dir = git_dir.join("commondir");
let worktree_and_common_dir = crate::path::from_plain_file(common_dir)
.and_then(Result::ok)
.and_then(|cd| {
crate::path::from_plain_file(git_dir.join("gitdir"))
.and_then(Result::ok)
.map(|worktree_gitfile| (crate::path::without_dot_git_dir(worktree_gitfile), cd))
});
match worktree_and_common_dir {
Some((work_dir, common_dir)) => {
let common_dir = git_dir.join(common_dir);
(
Cow::Borrowed(git_dir),
Cow::Owned(common_dir),
Kind::WorkTreeGitDir { work_dir },
)
}
None => (Cow::Borrowed(git_dir), Cow::Borrowed(git_dir), Kind::MaybeRepo),
}
};
{
// We expect to be able to parse any ref-hash, so we shouldn't have to know the repos hash here.
// With ref-table, the has is probably stored as part of the ref-db itself, so we can handle it from there.
// In other words, it's important not to fail on detached heads here because we guessed the hash kind wrongly.
let object_hash_should_not_matter_here = git_hash::Kind::Sha1;
let refs = git_ref::file::Store::at(
dot_git.as_ref(),
git_ref::store::WriteReflog::Normal,
object_hash_should_not_matter_here,
);
let head = refs.find_loose("HEAD")?;
if head.name.as_bstr() != "HEAD" {
return Err(crate::is_git::Error::MisplacedHead {
name: head.name.into_inner(),
});
}
}
{
let objects_path = common_dir.join("objects");
if !objects_path.is_dir() {
return Err(crate::is_git::Error::MissingObjectsDirectory { missing: objects_path });
}
}
{
let refs_path = common_dir.join("refs");
if !refs_path.is_dir() {
return Err(crate::is_git::Error::MissingRefsDirectory { missing: refs_path });
}
}
Ok(match kind {
Kind::LinkedWorkTreeDir => crate::repository::Kind::WorkTree {
linked_git_dir: Some(dot_git.into_owned()),
},
Kind::WorkTreeGitDir { work_dir } => crate::repository::Kind::WorkTreeGitDir { work_dir },
Kind::Submodule => crate::repository::Kind::Submodule {
git_dir: dot_git.into_owned(),
},
Kind::MaybeRepo => {
if bare(git_dir) {
crate::repository::Kind::Bare
} else if submodule_git_dir(git_dir) {
crate::repository::Kind::SubmoduleGitDir
} else {
crate::repository::Kind::WorkTree { linked_git_dir: None }
}
}
})
}