optimize
This commit is contained in:
@@ -240,17 +240,24 @@ fn open_with_cache(workdir: &Path) -> Result<gix::Repository> {
|
||||
Ok(repo)
|
||||
}
|
||||
|
||||
/// A [`FileCommit`] from a walk commit: author, message title and shortened id.
|
||||
fn file_commit(commit: &gix::Commit<'_>) -> Result<FileCommit> {
|
||||
/// A [`FileCommit`] from a walk commit: author, message title and shortened
|
||||
/// id. `include_description` controls whether the message body is copied;
|
||||
/// history lists never display it, so skipping it saves a string allocation
|
||||
/// per listed commit (the diff panel fetches the full commit on demand).
|
||||
fn file_commit(commit: &gix::Commit<'_>, include_description: bool) -> Result<FileCommit> {
|
||||
let author = commit.author()?;
|
||||
let message = commit.message()?;
|
||||
Ok(FileCommit {
|
||||
id: commit.id().shorten_or_id().to_string(),
|
||||
summary: String::from_utf8_lossy(message.title).trim().to_string(),
|
||||
description: message
|
||||
.body
|
||||
.map(|body| String::from_utf8_lossy(body).trim().to_string())
|
||||
.filter(|body| !body.is_empty()),
|
||||
description: if include_description {
|
||||
message
|
||||
.body
|
||||
.map(|body| String::from_utf8_lossy(body).trim().to_string())
|
||||
.filter(|body| !body.is_empty())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
author: String::from_utf8_lossy(author.name).trim().to_string(),
|
||||
time: author.time()?.seconds,
|
||||
})
|
||||
@@ -332,7 +339,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)?));
|
||||
found.push((rel.clone(), file_commit(&commit, true)?));
|
||||
pending.swap_remove(ix);
|
||||
} else {
|
||||
ix += 1;
|
||||
@@ -381,7 +388,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()?)?);
|
||||
commits.push(file_commit(&info.object()?, false)?);
|
||||
}
|
||||
}
|
||||
Ok(CommitList { total, commits })
|
||||
@@ -681,23 +688,29 @@ pub fn head_commit(repo: &gix::Repository) -> Result<Option<FileCommit>> {
|
||||
return Ok(None);
|
||||
};
|
||||
let commit = head.object()?.into_commit();
|
||||
let author = commit.author()?;
|
||||
let message = commit.message()?;
|
||||
Ok(Some(FileCommit {
|
||||
id: commit.id().shorten_or_id().to_string(),
|
||||
summary: String::from_utf8_lossy(message.title).trim().to_string(),
|
||||
description: message
|
||||
.body
|
||||
.map(|body| String::from_utf8_lossy(body).trim().to_string())
|
||||
.filter(|body| !body.is_empty()),
|
||||
author: String::from_utf8_lossy(author.name).trim().to_string(),
|
||||
time: author.time()?.seconds,
|
||||
}))
|
||||
Ok(Some(file_commit(&commit, true)?))
|
||||
}
|
||||
|
||||
/// Short names of local branches (`refs/heads/*`), sorted alphabetically.
|
||||
pub fn worktree_branches(workdir: &Path) -> Result<Vec<String>> {
|
||||
/// Full metadata of the commit `id` (short or full) in the repository at
|
||||
/// `workdir`, like [`head_commit`] for an arbitrary commit. Returns
|
||||
/// `Ok(None)` when the id cannot be resolved.
|
||||
///
|
||||
/// The commit list ([`all_commits`]) omits message bodies to keep the walk
|
||||
/// cheap; the diff panel uses this to fetch the full commit on demand.
|
||||
pub fn worktree_commit(workdir: &Path, id: &str) -> Result<Option<FileCommit>> {
|
||||
let repo = open_with_cache(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)?))
|
||||
}
|
||||
Err(_) => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// Short names of local branches (`refs/heads/*`) of `repo`, sorted
|
||||
/// alphabetically.
|
||||
pub fn repo_branches(repo: &gix::Repository) -> Result<Vec<String>> {
|
||||
let mut names = Vec::new();
|
||||
for reference in repo.references()?.local_branches()? {
|
||||
let reference = reference.map_err(|error| anyhow::anyhow!("{error}"))?;
|
||||
@@ -707,9 +720,8 @@ pub fn worktree_branches(workdir: &Path) -> Result<Vec<String>> {
|
||||
Ok(names)
|
||||
}
|
||||
|
||||
/// Short names of tags (`refs/tags/*`), sorted alphabetically.
|
||||
pub fn worktree_tags(workdir: &Path) -> Result<Vec<String>> {
|
||||
let repo = open_with_cache(workdir)?;
|
||||
/// Short names of tags (`refs/tags/*`) of `repo`, sorted alphabetically.
|
||||
pub fn repo_tags(repo: &gix::Repository) -> Result<Vec<String>> {
|
||||
let mut names = Vec::new();
|
||||
for reference in repo.references()?.tags()? {
|
||||
let reference = reference.map_err(|error| anyhow::anyhow!("{error}"))?;
|
||||
@@ -719,6 +731,16 @@ pub fn worktree_tags(workdir: &Path) -> Result<Vec<String>> {
|
||||
Ok(names)
|
||||
}
|
||||
|
||||
/// Short names of local branches (`refs/heads/*`), sorted alphabetically.
|
||||
pub fn worktree_branches(workdir: &Path) -> Result<Vec<String>> {
|
||||
repo_branches(&open_with_cache(workdir)?)
|
||||
}
|
||||
|
||||
/// Short names of tags (`refs/tags/*`), sorted alphabetically.
|
||||
pub fn worktree_tags(workdir: &Path) -> Result<Vec<String>> {
|
||||
repo_tags(&open_with_cache(workdir)?)
|
||||
}
|
||||
|
||||
/// Short name of the branch HEAD points to, or `None` when detached (e.g.
|
||||
/// after checking out a tag or a commit directly).
|
||||
pub fn current_branch(repo: &gix::Repository) -> Result<Option<String>> {
|
||||
|
||||
Reference in New Issue
Block a user