Skip to content

Commit

Permalink
Merge pull request rust-lang#126 from joshtriplett/git_repository_ope…
Browse files Browse the repository at this point in the history
…n_ext

Add binding for git_repository_open_ext
  • Loading branch information
alexcrichton committed Apr 3, 2016
2 parents 0828909 + 5589a1a commit 8fbe14b
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 2 deletions.
12 changes: 12 additions & 0 deletions libgit2-sys/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,14 @@ git_enum! {
}
}

git_enum! {
pub enum git_repository_open_flag_t {
GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0),
GIT_REPOSITORY_OPEN_CROSS_FS = (1 << 1),
GIT_REPOSITORY_OPEN_BARE = (1 << 2),
}
}

#[repr(C)]
pub struct git_repository_init_options {
pub version: c_uint,
Expand Down Expand Up @@ -1382,6 +1390,10 @@ extern {
pub fn git_repository_free(repo: *mut git_repository);
pub fn git_repository_open(repo: *mut *mut git_repository,
path: *const c_char) -> c_int;
pub fn git_repository_open_ext(repo: *mut *mut git_repository,
path: *const c_char,
flags: c_uint,
ceiling_dirs: *const c_char) -> c_int;
pub fn git_repository_init(repo: *mut *mut git_repository,
path: *const c_char,
is_bare: c_uint) -> c_int;
Expand Down
7 changes: 7 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::env::JoinPathsError;
use std::ffi::{CStr, NulError};
use std::error;
use std::fmt;
Expand Down Expand Up @@ -214,6 +215,12 @@ impl From<NulError> for Error {
}
}

impl From<JoinPathsError> for Error {
fn from(e: JoinPathsError) -> Error {
Error::from_str(error::Error::description(&e))
}
}


#[cfg(test)]
mod tests {
Expand Down
14 changes: 14 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,20 @@ Flags for APIs that add files matching pathspec
}
}

bitflags! {
#[doc = "
Flags for `Repository::open_ext`
"]
flags RepositoryOpenFlags: u32 {
/// Only open the specified path; don't walk upward searching.
const REPOSITORY_OPEN_NO_SEARCH = raw::GIT_REPOSITORY_OPEN_NO_SEARCH as u32,
/// Search across filesystem boundaries.
const REPOSITORY_OPEN_CROSS_FS = raw::GIT_REPOSITORY_OPEN_CROSS_FS as u32,
/// Force opening as bare repository, and defer loading its config.
const REPOSITORY_OPEN_BARE = raw::GIT_REPOSITORY_OPEN_BARE as u32,
}
}

bitflags! {
#[doc = "
Flags for the return value of `Repository::revparse`
Expand Down
67 changes: 65 additions & 2 deletions src/repo.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::ffi::{CStr, CString};
use std::env;
use std::ffi::{CStr, CString, OsStr};
use std::iter::IntoIterator;
use std::mem;
use std::path::Path;
use std::str;
use libc::{c_int, c_char, size_t, c_void, c_uint};

use {raw, Revspec, Error, init, Object, RepositoryState, Remote, Buf};
use {raw, Revspec, Error, init, Object, RepositoryOpenFlags, RepositoryState, Remote, Buf};
use {ResetType, Signature, Reference, References, Submodule, Blame, BlameOptions};
use {Branches, BranchType, Index, Config, Oid, Blob, Branch, Commit, Tree};
use {AnnotatedCommit, MergeOptions, SubmoduleIgnore, SubmoduleStatus};
Expand Down Expand Up @@ -59,6 +60,43 @@ impl Repository {
}
}

/// Find and open an existing repository, with additional options.
///
/// If flags contains REPOSITORY_OPEN_NO_SEARCH, the path must point
/// directly to a repository; otherwise, this may point to a subdirectory
/// of a repository, and `open_ext` will search up through parent
/// directories.
///
/// If flags contains REPOSITORY_OPEN_CROSS_FS, the search through parent
/// directories will not cross a filesystem boundary (detected when the
/// stat st_dev field changes).
///
/// If flags contains REPOSITORY_OPEN_BARE, force opening the repository as
/// bare even if it isn't, ignoring any working directory, and defer
/// loading the repository configuration for performance.
///
/// ceiling_dirs specifies a list of paths that the search through parent
/// directories will stop before entering. Use the functions in std::env
/// to construct or manipulate such a path list.
pub fn open_ext<P, O, I>(path: P,
flags: RepositoryOpenFlags,
ceiling_dirs: I)
-> Result<Repository, Error>
where P: AsRef<Path>, O: AsRef<OsStr>, I: IntoIterator<Item=O> {
init();
let path = try!(path.as_ref().into_c_string());
let ceiling_dirs_os = try!(env::join_paths(ceiling_dirs));
let ceiling_dirs = try!(ceiling_dirs_os.into_c_string());
let mut ret = 0 as *mut raw::git_repository;
unsafe {
try_call!(raw::git_repository_open_ext(&mut ret,
path,
flags.bits() as c_uint,
ceiling_dirs));
Ok(Binding::from_raw(ret))
}
}

/// Attempt to open an already-existing repository at or above `path`
///
/// This starts at `path` and looks up the filesystem hierarchy
Expand Down Expand Up @@ -1663,6 +1701,7 @@ impl RepositoryInitOptions {

#[cfg(test)]
mod tests {
use std::ffi::OsStr;
use std::fs;
use std::path::Path;
use tempdir::TempDir;
Expand Down Expand Up @@ -1754,6 +1793,30 @@ mod tests {
::test::realpath(&td.path().join("")).unwrap());
}

#[test]
fn smoke_open_ext() {
let td = TempDir::new("test").unwrap();
let subdir = td.path().join("subdir");
fs::create_dir(&subdir).unwrap();
Repository::init(td.path()).unwrap();

let repo = Repository::open_ext(&subdir, ::RepositoryOpenFlags::empty(), &[] as &[&OsStr]).unwrap();
assert!(!repo.is_bare());
assert_eq!(::test::realpath(&repo.path()).unwrap(),
::test::realpath(&td.path().join(".git")).unwrap());

let repo = Repository::open_ext(&subdir, ::REPOSITORY_OPEN_BARE, &[] as &[&OsStr]).unwrap();
assert!(repo.is_bare());
assert_eq!(::test::realpath(&repo.path()).unwrap(),
::test::realpath(&td.path().join(".git")).unwrap());

let err = Repository::open_ext(&subdir, ::REPOSITORY_OPEN_NO_SEARCH, &[] as &[&OsStr]).err().unwrap();
assert_eq!(err.code(), ::ErrorCode::NotFound);

let err = Repository::open_ext(&subdir, ::RepositoryOpenFlags::empty(), &[&subdir]).err().unwrap();
assert_eq!(err.code(), ::ErrorCode::NotFound);
}

fn graph_repo_init() -> (TempDir, Repository) {
let (_td, repo) = ::test::repo_init();
{
Expand Down

0 comments on commit 8fbe14b

Please sign in to comment.