|
|
|
@ -31,48 +31,30 @@ impl FileTree { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Get the history of a path with a branch iterator
|
|
|
|
|
///
|
|
|
|
|
/// This function is computationally light, by not checking for
|
|
|
|
|
/// renames between commits. This is done by resolving a path to
|
|
|
|
|
/// a tree reference, and comparing references at the same
|
|
|
|
|
/// position between two commits.
|
|
|
|
|
pub fn base_history(&self, iter: BranchIter, path: &str) -> Option<Vec<Commit>> { |
|
|
|
|
let mut iter = iter.peekable(); |
|
|
|
|
|
|
|
|
|
let entry = self.resolve(path)?; |
|
|
|
|
let trgid = entry.id(); |
|
|
|
|
|
|
|
|
|
let mut commits = vec![]; |
|
|
|
|
|
|
|
|
|
// Iterate over the branch in commit pairs
|
|
|
|
|
while let (Some(a), b) = iter.next_pair() { |
|
|
|
|
dbg!(&a.commit()); |
|
|
|
|
let ta = self.checkout(a.commit().id.clone()); |
|
|
|
|
let te_a = dbg!(ta.resolve(dbg!(path))); |
|
|
|
|
|
|
|
|
|
let b = match b { |
|
|
|
|
Some(b) => b, |
|
|
|
|
None if te_a.is_some() => { |
|
|
|
|
// If b doesn't exist, but the path exists in a,
|
|
|
|
|
// then it is safe to assume that a introduces the
|
|
|
|
|
// path
|
|
|
|
|
commits.push(a.commit().clone()); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
None => break, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
let tb = self.checkout(b.commit().id.clone()); |
|
|
|
|
let te_b = match ta.resolve(path) { |
|
|
|
|
Some(b) => b, |
|
|
|
|
None => continue, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
let te_a = match te_a { |
|
|
|
|
Some(a) => a, |
|
|
|
|
None => continue, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// If the two tree nodes are not equal, add the commit to
|
|
|
|
|
// the list. This means that the `a` commit changed
|
|
|
|
|
// something in the path.
|
|
|
|
|
if dbg!(te_a != te_b) { |
|
|
|
|
commits.push(a.commit().clone()); |
|
|
|
|
let _a = a.commit().clone(); |
|
|
|
|
let a = self.checkout(a.commit().id.clone()).resolve(path); |
|
|
|
|
let b = b.and_then(|c| self.checkout(c.commit().id.clone()).resolve(path)); |
|
|
|
|
|
|
|
|
|
match (a, b) { |
|
|
|
|
// If a path exists in both commits, check if they are
|
|
|
|
|
// the same Ref. If they are not, a changed the path.
|
|
|
|
|
(Some(a), Some(b)) if a != b => commits.push(_a), |
|
|
|
|
// If a path only exists in a then it was created
|
|
|
|
|
(Some(_), None) => commits.push(_a), |
|
|
|
|
// If a path only exists in b, then it was deleted
|
|
|
|
|
(None, Some(_)) => commits.push(_a), |
|
|
|
|
(_, _) => {} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|