Skip to main content

git_lfs_git/
path.rs

1//! Repository path discovery.
2
3use std::path::{Path, PathBuf};
4
5use crate::{Error, run_git};
6
7/// Path to the `.git` directory of the repository containing `cwd`. Always
8/// returns an absolute path. Errors if `cwd` isn't inside a git repository.
9pub fn git_dir(cwd: &Path) -> Result<PathBuf, Error> {
10    run_git(cwd, &["rev-parse", "--absolute-git-dir"]).map(PathBuf::from)
11}
12
13/// Path to the LFS storage directory for the repository (`<git-dir>/lfs`).
14/// The directory is not created.
15pub fn lfs_dir(cwd: &Path) -> Result<PathBuf, Error> {
16    Ok(git_dir(cwd)?.join("lfs"))
17}
18
19#[cfg(test)]
20mod tests {
21    use super::*;
22    use std::process::Command;
23    use tempfile::TempDir;
24
25    fn init_repo() -> TempDir {
26        let tmp = TempDir::new().unwrap();
27        let status = Command::new("git")
28            .args(["init", "--quiet"])
29            .arg(tmp.path())
30            .status()
31            .unwrap();
32        assert!(status.success(), "git init failed");
33        tmp
34    }
35
36    #[test]
37    fn git_dir_is_absolute() {
38        let tmp = init_repo();
39        let dir = git_dir(tmp.path()).unwrap();
40        assert!(dir.is_absolute(), "{dir:?}");
41        assert_eq!(dir.file_name().unwrap(), ".git");
42    }
43
44    #[test]
45    fn lfs_dir_under_git_dir() {
46        let tmp = init_repo();
47        let dir = lfs_dir(tmp.path()).unwrap();
48        assert!(dir.ends_with(".git/lfs"));
49    }
50
51    #[test]
52    fn outside_repo_errors() {
53        let tmp = TempDir::new().unwrap();
54        let err = git_dir(tmp.path()).unwrap_err();
55        assert!(matches!(err, Error::Failed(_)), "got {err:?}");
56    }
57}