Skip to content

Commit c93d29b

Browse files
authored
Merge pull request #883 from zed-industries/add-discover-path
Add implementation and test for discover_path
2 parents ae3660a + 7f55b95 commit c93d29b

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

src/repo.rs

+56-1
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
@@ -3428,6 +3455,34 @@ mod tests {
34283455
);
34293456
}
34303457

3458+
#[test]
3459+
fn smoke_discover_path() {
3460+
let td = TempDir::new().unwrap();
3461+
let subdir = td.path().join("subdi");
3462+
fs::create_dir(&subdir).unwrap();
3463+
Repository::init_bare(td.path()).unwrap();
3464+
let path = Repository::discover_path(&subdir, &[] as &[&OsStr]).unwrap();
3465+
assert_eq!(
3466+
crate::test::realpath(&path).unwrap(),
3467+
crate::test::realpath(&td.path().join("")).unwrap()
3468+
);
3469+
}
3470+
3471+
#[test]
3472+
fn smoke_discover_path_ceiling_dir() {
3473+
let td = TempDir::new().unwrap();
3474+
let subdir = td.path().join("subdi");
3475+
fs::create_dir(&subdir).unwrap();
3476+
let ceilingdir = subdir.join("ceiling");
3477+
fs::create_dir(&ceilingdir).unwrap();
3478+
let testdir = ceilingdir.join("testdi");
3479+
fs::create_dir(&testdir).unwrap();
3480+
Repository::init_bare(td.path()).unwrap();
3481+
let path = Repository::discover_path(&testdir, &[ceilingdir.as_os_str()]);
3482+
3483+
assert!(path.is_err());
3484+
}
3485+
34313486
#[test]
34323487
fn smoke_open_ext() {
34333488
let td = TempDir::new().unwrap();

0 commit comments

Comments
 (0)