Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ pub struct RepoStatus {
// with a call into it. The pure-Rust core is what carries the gix logic + tests.

#[pyfunction]
fn is_git_repo(_path: String) -> PyResult<bool> {
todo!("repo::is_git_repo (gix::discover)")
fn is_git_repo(path: String) -> PyResult<bool> {
Ok(crate::repo::is_git_repo(std::path::Path::new(&path)))
}

#[pyfunction]
Expand Down
86 changes: 86 additions & 0 deletions src/repo/is_git_repo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use gix::discover;
use std::path::Path;

/// Returns true iff `path` is inside a git working tree (mirrors
/// `git rev-parse --git-dir` exit==0).
pub fn is_git_repo(path: &Path) -> bool {
discover(path).is_ok()
}

#[cfg(test)]
mod tests {
use super::*;
use crate::repo::fixtures;
use std::process::Command;

#[test]
fn repo_root_and_subdir() {
let td = fixtures::repo();
let root_path = td.path();

// Test at the repo root
assert!(is_git_repo(root_path));

// Create a subdirectory and test there
let subdir_path = root_path.join("subdir");
std::fs::create_dir(&subdir_path).expect("mkdir");
assert!(is_git_repo(&subdir_path));
}

#[test]
fn non_repo() {
let td = tempfile::tempdir().expect("tempdir");
let non_repo_path = td.path();
assert!(!is_git_repo(non_repo_path));
}

#[test]
fn parity_with_git_cli() {
let repo_td = fixtures::repo();
let repo_path = repo_td.path();

// Check the repo path
assert_eq!(
is_git_repo(repo_path),
Command::new("git")
.args(["-C", &repo_path.to_string_lossy(), "rev-parse", "--git-dir"])
.status()
.expect("spawn git")
.success()
);

// Check a subdirectory within the repo
let subdir_path = repo_path.join("subdir");
std::fs::create_dir(&subdir_path).expect("mkdir");
assert_eq!(
is_git_repo(&subdir_path),
Command::new("git")
.args([
"-C",
&subdir_path.to_string_lossy(),
"rev-parse",
"--git-dir"
])
.status()
.expect("spawn git")
.success()
);

// Check a non-repo path
let non_repo_td = tempfile::tempdir().expect("tempdir");
let non_repo_path = non_repo_td.path();
assert_eq!(
is_git_repo(non_repo_path),
Command::new("git")
.args([
"-C",
&non_repo_path.to_string_lossy(),
"rev-parse",
"--git-dir"
])
.status()
.expect("spawn git")
.success()
);
}
}
3 changes: 3 additions & 0 deletions src/repo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ pub use crate::error::{GitxtendError, Result};
// ---- method registrations (one block per implemented method) -------------
// (methods land here as M1 progresses — see docs/ROADMAP.md M1 ordering)

mod is_git_repo;
pub use is_git_repo::is_git_repo;

/// Temp-dir git fixtures shared by the per-method parity tests.
///
/// Fixtures are built with the real `git` CLI, so each parity test asserts
Expand Down
Loading