Skip to main content

workon/
workon_root.rs

1use std::path::Path;
2
3use git2::Repository;
4
5use crate::error::{Result, WorktreeError};
6
7/// Resolve the directory that contains all worktrees for the repository.
8///
9/// For the standard bare-repo layout (`project/.bare`, `project/main`, …) this
10/// returns the `project/` directory — the common ancestor of the `.bare` git
11/// directory and any working directory.
12///
13/// Returns [`WorktreeError::NoParent`] if the path has no parent.
14pub fn workon_root(repo: &Repository) -> Result<&Path> {
15    let path = repo.path();
16
17    match repo.workdir() {
18        Some(workdir) if workdir != path => {
19            let repo_ancestors: Vec<_> = path.ancestors().collect();
20            let common_root = workdir
21                .ancestors()
22                .find(|ancestor| repo_ancestors.contains(ancestor));
23            if let Some(common_root) = common_root {
24                return Ok(common_root);
25            }
26        }
27        _ => {}
28    }
29
30    path.parent().ok_or(WorktreeError::NoParent.into())
31}