Skip to main content

nb_api/
git.rs

1//! Git repository detection helpers.
2//!
3//! Consumed by `nb-api` directly and by downstream tools (e.g.,
4//! `nb-mcp-server`'s `paths.rs`) via the published crate.
5
6use std::path::PathBuf;
7
8/// Derive the notebook name from the current Git repository.
9///
10/// Returns the directory name of the master repository (not the worktree).
11/// Used as a fallback when no explicit notebook name is configured.
12pub fn derive_git_notebook_name() -> Option<String> {
13    let current_root = git_rev_parse(&["--show-toplevel"])?;
14    let git_common_dir = git_rev_parse(&["--git-common-dir"])?;
15    let git_common_dir = if git_common_dir.is_relative() {
16        current_root.join(&git_common_dir)
17    } else {
18        git_common_dir
19    };
20    let git_common_dir = git_common_dir.canonicalize().ok()?;
21    let master_root = if git_common_dir.file_name().is_some_and(|n| n == ".git") {
22        git_common_dir.parent()?.to_path_buf()
23    } else {
24        return None;
25    };
26    master_root
27        .file_name()
28        .and_then(|name| name.to_str())
29        .map(|name| name.to_string())
30}
31
32/// Run `git rev-parse` with the given arguments and return the output as a path.
33///
34/// Returns `None` if git is not available, the command fails, or the output is empty.
35///
36/// Strips inherited `GIT_*` routing vars before spawning so the git
37/// invocation resolves the repository from its own cwd/args, not from
38/// the parent hook or CI environment. See `nb-api:issues/3`.
39pub fn git_rev_parse(args: &[&str]) -> Option<PathBuf> {
40    let mut command = std::process::Command::new("git");
41    crate::git_env::scrub_git_env_std(&mut command);
42    let output = command.args(["rev-parse"]).args(args).output().ok()?;
43    if !output.status.success() {
44        return None;
45    }
46    let stdout = String::from_utf8(output.stdout).ok()?;
47    let value = stdout.trim();
48    if value.is_empty() {
49        return None;
50    }
51    Some(PathBuf::from(value))
52}