Skip to content

Commit 4428838

Browse files
committed
refactor
1 parent fd63dd6 commit 4428838

File tree

2 files changed

+27
-68
lines changed

2 files changed

+27
-68
lines changed

gix-blame/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,8 @@ pub enum Error {
2929
DiffTree(#[from] gix_diff::tree::Error),
3030
#[error("Invalid line range was given, line range is expected to be a 1-based inclusive range in the format '<start>,<end>'")]
3131
InvalidLineRange,
32+
#[error("Failure to decode commit during traversal")]
33+
DecodeCommit(#[from] gix_object::decode::Error),
34+
#[error("Failed to get parent from commitgraph during traversal")]
35+
GetParentFromCommitGraph(#[from] gix_commitgraph::file::commit::Error),
3236
}

gix-blame/src/file/function.rs

Lines changed: 23 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use gix_object::{
77
bstr::{BStr, BString},
88
FindExt,
99
};
10-
use gix_traverse::commit::find;
10+
use gix_traverse::commit::find as find_commit;
1111
use smallvec::SmallVec;
1212
use std::num::NonZeroU32;
1313
use std::ops::Range;
@@ -79,13 +79,7 @@ pub fn file(
7979
commit_id: suspect,
8080
})?;
8181
let blamed_file_blob = odb.find_blob(&blamed_file_entry_id, &mut buf)?.data.to_vec();
82-
let num_lines_in_blamed = {
83-
let mut interner = gix_diff::blob::intern::Interner::new(blamed_file_blob.len() / 100);
84-
tokens_for_diffing(&blamed_file_blob)
85-
.tokenize()
86-
.map(|token| interner.intern(token))
87-
.count()
88-
} as u32;
82+
let num_lines_in_blamed = tokens_for_diffing(&blamed_file_blob).tokenize().count() as u32;
8983

9084
// Binary or otherwise empty?
9185
if num_lines_in_blamed == 0 {
@@ -98,36 +92,29 @@ pub fn file(
9892
suspects: [(suspect, range_in_blamed_file)].into(),
9993
}];
10094

101-
let mut buf = Vec::new();
102-
let commit = find(cache.as_ref(), &odb, &suspect, &mut buf)?;
103-
95+
let (mut buf, mut buf2) = (Vec::new(), Vec::new());
96+
let commit = find_commit(cache.as_ref(), &odb, &suspect, &mut buf)?;
10497
let mut queue: gix_revwalk::PriorityQueue<CommitTime, ObjectId> = gix_revwalk::PriorityQueue::new();
105-
106-
let commit_time = commit_time(commit);
107-
queue.insert(commit_time, suspect);
98+
queue.insert(commit_time(commit)?, suspect);
10899

109100
let mut out = Vec::new();
110101
let mut diff_state = gix_diff::tree::State::default();
111102
let mut previous_entry: Option<(ObjectId, ObjectId)> = None;
112103
'outer: while let Some(suspect) = queue.pop_value() {
104+
stats.commits_traversed += 1;
113105
if hunks_to_blame.is_empty() {
114106
break;
115107
}
116108

117109
let is_still_suspect = hunks_to_blame.iter().any(|hunk| hunk.suspects.contains_key(&suspect));
118-
119110
if !is_still_suspect {
120111
// There are no `UnblamedHunk`s associated with this `suspect`, so we can continue with
121112
// the next one.
122113
continue 'outer;
123114
}
124115

125-
stats.commits_traversed += 1;
126-
127-
let commit = find(cache.as_ref(), &odb, &suspect, &mut buf)?;
128-
129-
let parent_ids: ParentIds = collect_parents(commit, &odb, cache.as_ref());
130-
116+
let commit = find_commit(cache.as_ref(), &odb, &suspect, &mut buf)?;
117+
let parent_ids: ParentIds = collect_parents(commit, &odb, cache.as_ref(), &mut buf2)?;
131118
if parent_ids.is_empty() {
132119
if queue.is_empty() {
133120
// I’m not entirely sure if this is correct yet. `suspect`, at this point, is the
@@ -139,7 +126,6 @@ pub fn file(
139126
break 'outer;
140127
}
141128
}
142-
143129
// There is more, keep looking.
144130
continue;
145131
}
@@ -639,27 +625,12 @@ fn find_path_entry_in_commit(
639625

640626
type CommitTime = i64;
641627

642-
fn commit_time(commit: gix_traverse::commit::Either<'_, '_>) -> CommitTime {
628+
fn commit_time(commit: gix_traverse::commit::Either<'_, '_>) -> Result<CommitTime, gix_object::decode::Error> {
643629
match commit {
644630
gix_traverse::commit::Either::CommitRefIter(commit_ref_iter) => {
645-
let mut commit_time = 0;
646-
for token in commit_ref_iter {
647-
use gix_object::commit::ref_iter::Token as T;
648-
match token {
649-
Ok(T::Tree { .. }) => continue,
650-
Ok(T::Parent { .. }) => continue,
651-
Ok(T::Author { .. }) => continue,
652-
Ok(T::Committer { signature }) => {
653-
commit_time = signature.time.seconds;
654-
break;
655-
}
656-
Ok(_unused_token) => break,
657-
Err(_err) => todo!(),
658-
}
659-
}
660-
commit_time
631+
commit_ref_iter.committer().map(|c| c.time.seconds)
661632
}
662-
gix_traverse::commit::Either::CachedCommit(commit) => commit.committer_timestamp() as i64,
633+
gix_traverse::commit::Either::CachedCommit(commit) => Ok(commit.committer_timestamp() as i64),
663634
}
664635
}
665636

@@ -669,46 +640,30 @@ fn collect_parents(
669640
commit: gix_traverse::commit::Either<'_, '_>,
670641
odb: &impl gix_object::Find,
671642
cache: Option<&gix_commitgraph::Graph>,
672-
) -> ParentIds {
643+
buf: &mut Vec<u8>,
644+
) -> Result<ParentIds, Error> {
673645
let mut parent_ids: ParentIds = Default::default();
674-
675646
match commit {
676647
gix_traverse::commit::Either::CachedCommit(commit) => {
677648
let cache = cache
678649
.as_ref()
679650
.expect("find returned a cached commit, so we expect cache to be present");
680-
for parent_id in commit.iter_parents() {
681-
match parent_id {
682-
Ok(pos) => {
683-
let parent = cache.commit_at(pos);
684-
685-
parent_ids.push((parent.id().to_owned(), parent.committer_timestamp() as i64));
686-
}
687-
Err(_) => todo!(),
688-
}
651+
for parent_pos in commit.iter_parents() {
652+
let parent = cache.commit_at(parent_pos?);
653+
parent_ids.push((parent.id().to_owned(), parent.committer_timestamp() as i64));
689654
}
690655
}
691656
gix_traverse::commit::Either::CommitRefIter(commit_ref_iter) => {
692-
for token in commit_ref_iter {
693-
match token {
694-
Ok(gix_object::commit::ref_iter::Token::Tree { .. }) => continue,
695-
Ok(gix_object::commit::ref_iter::Token::Parent { id }) => {
696-
let mut buf = Vec::new();
697-
let parent = odb.find_commit_iter(id.as_ref(), &mut buf).ok();
698-
let parent_commit_time = parent
699-
.and_then(|parent| parent.committer().ok().map(|committer| committer.time.seconds))
700-
.unwrap_or_default();
701-
702-
parent_ids.push((id, parent_commit_time));
703-
}
704-
Ok(_unused_token) => break,
705-
Err(_err) => todo!(),
706-
}
657+
for id in commit_ref_iter.parent_ids() {
658+
let parent = odb.find_commit_iter(id.as_ref(), buf).ok();
659+
let parent_commit_time = parent
660+
.and_then(|parent| parent.committer().ok().map(|committer| committer.time.seconds))
661+
.unwrap_or_default();
662+
parent_ids.push((id, parent_commit_time));
707663
}
708664
}
709665
};
710-
711-
parent_ids
666+
Ok(parent_ids)
712667
}
713668

714669
/// Return an iterator over tokens for use in diffing. These are usually lines, but it's important

0 commit comments

Comments
 (0)