Skip to content

Commit 7f55b95

Browse files
committed
Add implementation and test for discover_path
1 parent 49879e9 commit 7f55b95

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

src/repo.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::env;
33
use std::ffi::{CStr, CString, OsStr};
44
use std::iter::IntoIterator;
55
use std::mem;
6-
use std::path::Path;
6+
use std::path::{Path, PathBuf};
77
use std::ptr;
88
use std::str;
99

@@ -259,6 +259,33 @@ impl Repository {
259259
Repository::open(util::bytes2path(&*buf))
260260
}
261261

262+
/// Attempt to find the path to a git repo for a given path
263+
///
264+
/// This starts at `path` and looks up the filesystem hierarchy
265+
/// until it finds a repository, stopping if it finds a member of ceiling_dirs
266+
pub fn discover_path<P: AsRef<Path>, I, O>(path: P, ceiling_dirs: I) -> Result<PathBuf, Error>
267+
where
268+
O: AsRef<OsStr>,
269+
I: IntoIterator<Item = O>,
270+
{
271+
crate::init();
272+
let buf = Buf::new();
273+
// Normal file path OK (does not need Windows conversion).
274+
let path = path.as_ref().into_c_string()?;
275+
let ceiling_dirs_os = env::join_paths(ceiling_dirs)?;
276+
let ceiling_dirs = ceiling_dirs_os.into_c_string()?;
277+
unsafe {
278+
try_call!(raw::git_repository_discover(
279+
buf.raw(),
280+
path,
281+
1,
282+
ceiling_dirs
283+
));
284+
}
285+
286+
Ok(util::bytes2path(&*buf).to_path_buf())
287+
}
288+
262289
/// Creates a new repository in the specified folder.
263290
///
264291
/// This by default will create any necessary directories to create the
@@ -3412,6 +3439,34 @@ mod tests {
34123439
);
34133440
}
34143441

3442+
#[test]
3443+
fn smoke_discover_path() {
3444+
let td = TempDir::new().unwrap();
3445+
let subdir = td.path().join("subdi");
3446+
fs::create_dir(&subdir).unwrap();
3447+
Repository::init_bare(td.path()).unwrap();
3448+
let path = Repository::discover_path(&subdir, &[] as &[&OsStr]).unwrap();
3449+
assert_eq!(
3450+
crate::test::realpath(&path).unwrap(),
3451+
crate::test::realpath(&td.path().join("")).unwrap()
3452+
);
3453+
}
3454+
3455+
#[test]
3456+
fn smoke_discover_path_ceiling_dir() {
3457+
let td = TempDir::new().unwrap();
3458+
let subdir = td.path().join("subdi");
3459+
fs::create_dir(&subdir).unwrap();
3460+
let ceilingdir = subdir.join("ceiling");
3461+
fs::create_dir(&ceilingdir).unwrap();
3462+
let testdir = ceilingdir.join("testdi");
3463+
fs::create_dir(&testdir).unwrap();
3464+
Repository::init_bare(td.path()).unwrap();
3465+
let path = Repository::discover_path(&testdir, &[ceilingdir.as_os_str()]);
3466+
3467+
assert!(path.is_err());
3468+
}
3469+
34153470
#[test]
34163471
fn smoke_open_ext() {
34173472
let td = TempDir::new().unwrap();

0 commit comments

Comments
 (0)