aboutsummaryrefslogtreecommitdiff
path: root/src/git/log.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/git/log.rs')
-rw-r--r--src/git/log.rs57
1 files changed, 34 insertions, 23 deletions
diff --git a/src/git/log.rs b/src/git/log.rs
index 97101cf..c8f4aa3 100644
--- a/src/git/log.rs
+++ b/src/git/log.rs
@@ -1,7 +1,7 @@
//! libgit2 log parsing
-use crate::git::{self, tree::FileNode};
-use git2::{Oid, Repository};
+use crate::git::{tree::FileNode, Repo};
+use git2::Oid;
use std::collections::{BTreeMap, BTreeSet};
/// A file-commit referenced graph thing
@@ -17,8 +17,11 @@ use std::collections::{BTreeMap, BTreeSet};
/// change" and it will tell you (sort of).
#[derive(Debug, Default)]
pub(crate) struct CommitGraph {
+ /// The correct order of commits in the log
order: Vec<String>,
- file_refs: BTreeMap<String, BTreeSet<String>>,
+ /// List of all files, and the commits in which they were touched
+ file_refs: BTreeMap<String, Vec<String>>,
+ /// Map of commit IDs to metadata
commit_refs: BTreeMap<String, CommitNode>,
}
@@ -31,19 +34,19 @@ pub(crate) struct CommitNode {
time: i64,
}
-fn build_diff_log(repo: &Repository, log: Vec<(String, Vec<FileNode>)>) -> Vec<CommitNode> {
+fn build_diff_log(repo: &Repo, log: Vec<(String, Vec<FileNode>)>) -> Vec<CommitNode> {
todo!()
}
/// Walk through all commits from a given ref and build a commit graph
-pub(crate) fn create_commit_log(id: String, repo: &Repository) -> CommitGraph {
- let mut walker = repo.revwalk().unwrap();
- walker.push(Oid::from_str(id.as_str()).unwrap()).unwrap();
+pub(crate) fn create_commit_log(rev: String, repo: &Repo) -> CommitGraph {
+ let mut walker = repo.get_inner().revwalk().unwrap();
+ walker.push(Oid::from_str(rev.as_str()).unwrap()).unwrap();
let mut commits = walker
.into_iter()
.map(|oid| {
let oid = oid.unwrap();
- repo.find_commit(oid).unwrap()
+ repo.get_inner().find_commit(oid).unwrap()
})
.collect::<Vec<_>>();
commits.reverse();
@@ -52,7 +55,7 @@ pub(crate) fn create_commit_log(id: String, repo: &Repository) -> CommitGraph {
.into_iter()
.map(|commit| {
let id = format!("{}", commit.id());
- (id.clone(), git::repo::get_tree(&repo, id.as_str()))
+ (id.clone(), repo.get_tree(id.as_str()))
})
.collect();
@@ -64,43 +67,51 @@ pub(crate) fn create_commit_log(id: String, repo: &Repository) -> CommitGraph {
let (commit_refs, file_refs) = log.into_iter().fold(
(BTreeMap::new(), BTreeMap::new()),
|(mut cm, mut fm), (cid, current)| {
+ let commit_id = format!("{}", cid);
+
let d = repo
+ .get_inner()
.diff_tree_to_tree(Some(&previous), Some(&current), None)
.unwrap();
- let files = d.deltas().fold(BTreeSet::new(), |mut set, delta| {
- set.insert(format!("{}", delta.new_file().id()));
+
+ // Store the commit to preserve order
+ order.push(commit_id.clone());
+
+ // For each file, store this commit as one that touched it
+ let touches = d.deltas().fold(BTreeSet::new(), |mut set, delta| {
+ let file_id = format!("{}", delta.new_file().id());
+ fm.entry(file_id.clone())
+ .or_insert(vec![])
+ .push(commit_id.clone());
+ set.insert(file_id);
set
});
- order.push(cid.clone());
- fm.insert(cid.clone(), files.clone());
-
+ // From the commit, build a metadata object
let commit_u = repo
+ .get_inner()
.find_commit(Oid::from_str(cid.as_str()).unwrap())
.unwrap();
let author_u = commit_u.author();
let commit = CommitNode {
- id: cid.clone(),
+ id: commit_id,
message: commit_u.message().unwrap().to_owned(),
author: format!("{} {}", author_u.name().unwrap(), author_u.email().unwrap()),
- touches: files,
+ touches,
time: author_u.when().seconds(),
};
+ // Insert the metadata object
cm.insert(cid.clone(), commit);
+ // We pass both the modified maps into the next commit
(cm, fm)
},
);
- let graph = CommitGraph {
+ CommitGraph {
order,
file_refs,
commit_refs,
- };
-
- dbg!(graph);
-
- // let diffs = build_diff_log(&repo, log);
- todo!()
+ }
}