Skip to content

Commit

Permalink
Add bare-resilient GitPath::repo_root (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
9999years authored Oct 18, 2024
1 parent f925b56 commit b58b653
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/git/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ use std::fmt::Debug;

use camino::Utf8PathBuf;
use command_error::CommandExt;
use command_error::OutputContext;
use miette::miette;
use miette::Context;
use miette::IntoDiagnostic;
use tracing::instrument;
use utf8_command::Utf8Output;

use crate::NormalPath;

use super::Git;

Expand All @@ -23,6 +28,43 @@ impl<'a> GitPath<'a> {
Self(git)
}

/// If in a working tree, get the repository root (`git rev-parse --show-toplevel`). If the
/// repository is bare, get the `.git` directory (`git rev-parse --git-dir`). Otherwise, error.
#[instrument(level = "trace")]
pub fn repo_root_or_git_common_dir_if_bare(&self) -> miette::Result<Utf8PathBuf> {
if self.is_inside_work_tree()? {
self.repo_root()
} else if self.0.config().is_bare()? {
self.git_common_dir()
} else {
Err(miette!(
"Path is not in a working tree or a bare repository: {}",
NormalPath::try_display_cwd(self.0.get_directory())
))
}
}

/// Check if we're inside a working tree.
#[instrument(level = "trace")]
pub fn is_inside_work_tree(&self) -> miette::Result<bool> {
self.0
.rev_parse_command()
.arg("--is-inside-work-tree")
.output_checked_as(|context: OutputContext<Utf8Output>| {
if !context.status().success() {
Err(context.error())
} else {
let stdout = context.output().stdout.trim();
match stdout {
"true" => Ok(true),
"false" => Ok(false),
_ => Err(context.error_msg("Expected 'true' or 'false'")),
}
}
})
.into_diagnostic()
}

/// `git rev-parse --show-toplevel`
#[instrument(level = "trace")]
pub fn repo_root(&self) -> miette::Result<Utf8PathBuf> {
Expand Down

0 comments on commit b58b653

Please sign in to comment.