Skip to content

Commit

Permalink
Query the cwd only once instead of potentially multiple times, allo…
Browse files Browse the repository at this point in the history
…cating a Vec each time. (#482)
  • Loading branch information
Byron committed Aug 17, 2022
1 parent 1b0ef18 commit 6be38f2
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 27 deletions.
57 changes: 33 additions & 24 deletions git-discover/src/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,47 @@ mod path {
/// Instantiate a new path from `dir` which is expected to be the `.git` directory, with `kind` indicating
/// whether it's a bare repository or not.
pub fn from_dot_git_dir(dir: impl Into<PathBuf>, kind: Kind) -> Self {
fn absolutize_on_trailing_dot_dot(dir: PathBuf) -> PathBuf {
Self::from_dot_git_dir_inner(dir, kind, std::env::current_dir().ok())
}
/// Returns the [kind][Kind] of this repository path.
pub fn kind(&self) -> Kind {
match self {
Path::LinkedWorkTree { work_dir: _, git_dir } => Kind::WorkTree {
linked_git_dir: Some(git_dir.to_owned()),
},
Path::WorkTree(_) => Kind::WorkTree { linked_git_dir: None },
Path::Repository(_) => Kind::Bare,
}
}

/// Consume and split this path into the location of the `.git` directory as well as an optional path to the work tree.
pub fn into_repository_and_work_tree_directories(self) -> (PathBuf, Option<PathBuf>) {
match self {
Path::LinkedWorkTree { work_dir, git_dir } => (git_dir, Some(work_dir)),
Path::WorkTree(working_tree) => (working_tree.join(DOT_GIT_DIR), Some(working_tree)),
Path::Repository(repository) => (repository, None),
}
}
}

impl Path {
pub(crate) fn from_dot_git_dir_inner(
dir: impl Into<PathBuf>,
kind: Kind,
current_dir: Option<PathBuf>,
) -> Self {
let absolutize_on_trailing_dot_dot = |dir: PathBuf| -> PathBuf {
if !matches!(dir.components().rev().next(), Some(std::path::Component::ParentDir)) {
dir
} else {
git_path::absolutize(&dir, std::env::current_dir().ok()).into_owned()
git_path::absolutize(&dir, current_dir.as_deref()).into_owned()
}
}
};

let dir = dir.into();
match kind {
Kind::Submodule { git_dir } => Path::LinkedWorkTree {
git_dir: git_path::absolutize(git_dir, std::env::current_dir().ok()).into_owned(),
git_dir: git_path::absolutize(git_dir, current_dir.as_deref()).into_owned(),
work_dir: without_dot_git_dir(absolutize_on_trailing_dot_dot(dir)),
},
Kind::SubmoduleGitDir => Path::Repository(dir),
Expand All @@ -77,25 +106,6 @@ mod path {
Kind::Bare => Path::Repository(dir),
}
}
/// Returns the [kind][Kind] of this repository path.
pub fn kind(&self) -> Kind {
match self {
Path::LinkedWorkTree { work_dir: _, git_dir } => Kind::WorkTree {
linked_git_dir: Some(git_dir.to_owned()),
},
Path::WorkTree(_) => Kind::WorkTree { linked_git_dir: None },
Path::Repository(_) => Kind::Bare,
}
}

/// Consume and split this path into the location of the `.git` directory as well as an optional path to the work tree.
pub fn into_repository_and_work_tree_directories(self) -> (PathBuf, Option<PathBuf>) {
match self {
Path::LinkedWorkTree { work_dir, git_dir } => (git_dir, Some(work_dir)),
Path::WorkTree(working_tree) => (working_tree.join(DOT_GIT_DIR), Some(working_tree)),
Path::Repository(repository) => (repository, None),
}
}
}
}

Expand All @@ -105,7 +115,6 @@ pub enum Kind {
/// A bare repository does not have a work tree, that is files on disk beyond the `git` repository itself.
///
/// Note that this is merely a guess at this point as we didn't read the configuration yet.
/// It might also be the clone of a submodule in `.git/modules` which has its worktree configured with `core.worktree`.
Bare,
/// A `git` repository along with a checked out files in a work tree.
WorkTree {
Expand Down
4 changes: 2 additions & 2 deletions git-discover/src/upwards/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ pub(crate) mod function {
Some(trust) => {
// TODO: test this more, it definitely doesn't always find the shortest path to a directory
let path = if dir_made_absolute {
shorten_path_with_cwd(cursor, cwd)
shorten_path_with_cwd(cursor, cwd.as_deref())
} else {
cursor
};
break 'outer Ok((crate::repository::Path::from_dot_git_dir(path, kind), trust));
break 'outer Ok((crate::repository::Path::from_dot_git_dir_inner(path, kind, cwd), trust));
}
None => {
break 'outer Err(Error::NoTrustedGitRepository {
Expand Down
2 changes: 1 addition & 1 deletion git-discover/src/upwards/util.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::DOT_GIT_DIR;
use std::path::{Path, PathBuf};

pub(crate) fn shorten_path_with_cwd(cursor: PathBuf, cwd: Option<PathBuf>) -> PathBuf {
pub(crate) fn shorten_path_with_cwd(cursor: PathBuf, cwd: Option<&Path>) -> PathBuf {
fn comp_len(c: std::path::Component<'_>) -> usize {
use std::path::Component::*;
match c {
Expand Down

0 comments on commit 6be38f2

Please sign in to comment.