refactor
This commit is contained in:
@@ -71,7 +71,7 @@ const SCAN_MAX_DEPTH: usize = 12;
|
||||
/// Directories never descended into during a scan.
|
||||
///
|
||||
/// Dependency caches can be enormous without ever containing user repositories.
|
||||
const SCAN_SKIPPED_DIRS: [&str; 1] = ["node_modules"];
|
||||
const SCAN_SKIPPED_DIR: &str = "node_modules";
|
||||
|
||||
/// Walk `root` recursively and collect the paths of git repositories below it.
|
||||
pub fn find_git_repos(root: &Path) -> Vec<PathBuf> {
|
||||
@@ -107,7 +107,7 @@ pub fn find_git_repos(root: &Path) -> Vec<PathBuf> {
|
||||
}
|
||||
let file_name = entry.file_name();
|
||||
let name = file_name.to_string_lossy();
|
||||
if name.starts_with('.') || SCAN_SKIPPED_DIRS.contains(&name.as_ref()) {
|
||||
if name.starts_with('.') || name == SCAN_SKIPPED_DIR {
|
||||
continue;
|
||||
}
|
||||
stack.push((entry.path(), depth + 1));
|
||||
@@ -708,7 +708,8 @@ pub fn sanitize_path_component(id: &str) -> String {
|
||||
|
||||
/// In-memory object cache for history walks, see [`open_with_cache`].
|
||||
///
|
||||
/// Without one, every walk re-decodes the same commit objects from the object database.
|
||||
/// Without one, a walk re-decodes the same commit objects from the object database.
|
||||
/// Sized generously: a walk can cover a large portion of the repository's history.
|
||||
const OBJECT_CACHE_BYTES: usize = 64 * 1024 * 1024;
|
||||
|
||||
/// Metadata of a commit, as shown in the repository browser's file header.
|
||||
@@ -797,21 +798,35 @@ pub fn find_readme(repo: &gix::Repository) -> Result<Option<PathBuf>> {
|
||||
.and_then(|path| path.strip_prefix(workdir).ok().map(Path::to_path_buf)))
|
||||
}
|
||||
|
||||
/// Open the repository at `workdir` with an in-memory object cache sized for history walks.
|
||||
/// Open the repository at `workdir` with an in-memory object cache.
|
||||
///
|
||||
/// Only history walks use it, they re-decode the same commit objects repeatedly.
|
||||
/// Single-object reads open the repository plain.
|
||||
fn open_with_cache(workdir: &Path) -> Result<gix::Repository> {
|
||||
let mut repo = gix::open(workdir)?;
|
||||
repo.object_cache_size_if_unset(OBJECT_CACHE_BYTES);
|
||||
Ok(repo)
|
||||
}
|
||||
|
||||
/// A [`FileCommit`] from a walk commit, with author, message title and shortened id.
|
||||
/// `include_description` controls whether the message body is copied.
|
||||
///
|
||||
/// History lists never display it,
|
||||
/// so skipping it saves an allocation per listed commit.
|
||||
/// A [`FileCommit`] from a commit, with author, message title, body and shortened id.
|
||||
///
|
||||
/// The diff panel fetches the full commit on demand.
|
||||
fn file_commit(commit: &gix::Commit<'_>, include_description: bool) -> Result<FileCommit> {
|
||||
fn file_commit(commit: &gix::Commit<'_>) -> Result<FileCommit> {
|
||||
file_commit_with_description(commit, true)
|
||||
}
|
||||
|
||||
/// A [`FileCommit`] without the message body, for history lists that never display it.
|
||||
///
|
||||
/// Skipping the body saves an allocation per listed commit.
|
||||
fn file_commit_summary(commit: &gix::Commit<'_>) -> Result<FileCommit> {
|
||||
file_commit_with_description(commit, false)
|
||||
}
|
||||
|
||||
/// [`file_commit`] and [`file_commit_summary`], `include_description` picks the body.
|
||||
fn file_commit_with_description(
|
||||
commit: &gix::Commit<'_>,
|
||||
include_description: bool,
|
||||
) -> Result<FileCommit> {
|
||||
let author = commit.author()?;
|
||||
let message = commit.message()?;
|
||||
Ok(FileCommit {
|
||||
@@ -903,7 +918,7 @@ fn last_commits(repo: &gix::Repository, rels: &[PathBuf]) -> Result<Vec<(PathBuf
|
||||
|
||||
if blob.map(|entry| entry.id().detach()) != parent_blob.map(|entry| entry.id().detach())
|
||||
{
|
||||
found.push((rel.clone(), file_commit(&commit, true)?));
|
||||
found.push((rel.clone(), file_commit(&commit)?));
|
||||
pending.swap_remove(ix);
|
||||
} else {
|
||||
ix += 1;
|
||||
@@ -952,7 +967,7 @@ pub fn all_commits(repo: &gix::Repository) -> Result<CommitList> {
|
||||
let info = info?;
|
||||
total += 1;
|
||||
if commits.len() < MAX_LISTED_COMMITS {
|
||||
commits.push(file_commit(&info.object()?, false)?);
|
||||
commits.push(file_commit_summary(&info.object()?)?);
|
||||
}
|
||||
}
|
||||
Ok(CommitList { total, commits })
|
||||
@@ -1040,7 +1055,7 @@ pub struct CommitDiff {
|
||||
///
|
||||
/// Compared against its first parent, the empty tree for the root commit.
|
||||
pub fn worktree_commit_diff(workdir: &Path, id: &str) -> Result<CommitDiff> {
|
||||
commit_diff(&open_with_cache(workdir)?, id)
|
||||
commit_diff(&gix::open(workdir)?, id)
|
||||
}
|
||||
|
||||
fn commit_diff(repo: &gix::Repository, id: &str) -> Result<CommitDiff> {
|
||||
@@ -1058,7 +1073,7 @@ fn commit_diff(repo: &gix::Repository, id: &str) -> Result<CommitDiff> {
|
||||
///
|
||||
/// Directories and submodules are skipped, files are sorted by path.
|
||||
pub fn worktree_commit_range_diff(workdir: &Path, base: &str, tip: &str) -> Result<CommitDiff> {
|
||||
let repo = open_with_cache(workdir)?;
|
||||
let repo = gix::open(workdir)?;
|
||||
let base_tree = repo
|
||||
.rev_parse_single(base.as_bytes())?
|
||||
.object()?
|
||||
@@ -1093,7 +1108,7 @@ pub fn worktree_commit_range_commits(
|
||||
let mut commits = Vec::new();
|
||||
for info in walk.all()? {
|
||||
let info = info?;
|
||||
commits.push(file_commit(&info.object()?, false)?);
|
||||
commits.push(file_commit_summary(&info.object()?)?);
|
||||
}
|
||||
Ok(commits)
|
||||
}
|
||||
@@ -1667,7 +1682,7 @@ pub fn head_commit(repo: &gix::Repository) -> Result<Option<FileCommit>> {
|
||||
return Ok(None);
|
||||
};
|
||||
let commit = head.object()?.into_commit();
|
||||
Ok(Some(file_commit(&commit, true)?))
|
||||
Ok(Some(file_commit(&commit)?))
|
||||
}
|
||||
|
||||
/// Full metadata of the commit `id`, short or full, in the repository at `workdir`.
|
||||
@@ -1675,11 +1690,11 @@ pub fn head_commit(repo: &gix::Repository) -> Result<Option<FileCommit>> {
|
||||
///
|
||||
/// `Ok(None)` when the id cannot be resolved.
|
||||
pub fn worktree_commit(workdir: &Path, id: &str) -> Result<Option<FileCommit>> {
|
||||
let repo = open_with_cache(workdir)?;
|
||||
let repo = gix::open(workdir)?;
|
||||
match repo.rev_parse_single(id.as_bytes()) {
|
||||
Ok(commit_id) => {
|
||||
let commit = commit_id.object()?.into_commit();
|
||||
Ok(Some(file_commit(&commit, true)?))
|
||||
Ok(Some(file_commit(&commit)?))
|
||||
}
|
||||
Err(_) => Ok(None),
|
||||
}
|
||||
@@ -1709,7 +1724,7 @@ pub fn repo_tags(repo: &gix::Repository) -> Result<Vec<String>> {
|
||||
|
||||
/// Short names of local branches, `refs/heads/*`, sorted alphabetically.
|
||||
pub fn worktree_branches(workdir: &Path) -> Result<Vec<String>> {
|
||||
repo_branches(&open_with_cache(workdir)?)
|
||||
repo_branches(&gix::open(workdir)?)
|
||||
}
|
||||
|
||||
/// Short name of the branch HEAD points to, or `None` when detached.
|
||||
@@ -1770,7 +1785,7 @@ pub fn repo_ref_state(repo: &gix::Repository) -> Result<RepoRefState> {
|
||||
|
||||
/// [`repo_ref_state`] for the repository at `workdir`.
|
||||
pub fn worktree_ref_state(workdir: &Path) -> Result<RepoRefState> {
|
||||
repo_ref_state(&open_with_cache(workdir)?)
|
||||
repo_ref_state(&gix::open(workdir)?)
|
||||
}
|
||||
|
||||
/// Everything the browser needs to refresh after a branch or tag switch.
|
||||
@@ -1791,7 +1806,7 @@ pub struct WorktreeSnapshot {
|
||||
///
|
||||
/// Collects entries, the README, the branch HEAD points to and its commit.
|
||||
pub fn worktree_snapshot(workdir: &Path) -> Result<WorktreeSnapshot> {
|
||||
let repo = open_with_cache(workdir)?;
|
||||
let repo = gix::open(workdir)?;
|
||||
let readme_path = find_readme(&repo)?;
|
||||
let readme = match &readme_path {
|
||||
Some(path) => worktree_read(&repo, path)?,
|
||||
|
||||
Reference in New Issue
Block a user