aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2020-06-22 10:17:52 +0200
committerKatharina Fey <kookie@spacekookie.de>2020-06-22 10:17:52 +0200
commit367cb0b2358be04d18dfea963d1c42044893e3b4 (patch)
tree483b9a06ab6704bf812533ca403f54bb712e548c
parente30713b84bc9e66f7a8e8d2f51e953472cac28e4 (diff)
git/log: adding a lot of parsing code to make libgit2 useful
-rw-r--r--src/git/log.rs63
1 files changed, 54 insertions, 9 deletions
diff --git a/src/git/log.rs b/src/git/log.rs
index dab9e69..97101cf 100644
--- a/src/git/log.rs
+++ b/src/git/log.rs
@@ -15,18 +15,20 @@ use std::collections::{BTreeMap, BTreeSet};
/// heavily parse the log. This type here is the result of this
/// parsing: you can ask it smart questions like "when did this file
/// change" and it will tell you (sort of).
-#[derive(Default)]
+#[derive(Debug, Default)]
pub(crate) struct CommitGraph {
order: Vec<String>,
file_refs: BTreeMap<String, BTreeSet<String>>,
commit_refs: BTreeMap<String, CommitNode>,
}
+#[derive(Debug)]
pub(crate) struct CommitNode {
id: String,
author: String,
+ message: String,
touches: BTreeSet<String>,
- date: String,
+ time: i64,
}
fn build_diff_log(repo: &Repository, log: Vec<(String, Vec<FileNode>)>) -> Vec<CommitNode> {
@@ -37,25 +39,68 @@ fn build_diff_log(repo: &Repository, log: Vec<(String, Vec<FileNode>)>) -> Vec<C
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();
- let mut v = walker
+ let mut commits = walker
.into_iter()
.map(|oid| {
let oid = oid.unwrap();
repo.find_commit(oid).unwrap()
})
.collect::<Vec<_>>();
- v.reverse();
+ commits.reverse();
- let log: Vec<_> = v
+ let mut initial: Vec<(_, _)> = commits
.into_iter()
.map(|commit| {
let id = format!("{}", commit.id());
- let tree_u = git::repo::get_tree(&repo, id.as_str());
- let tree = git::tree::parse_tree(tree_u, &repo);
- (id, tree.flatten())
+ (id.clone(), git::repo::get_tree(&repo, id.as_str()))
})
.collect();
- let diffs = build_diff_log(&repo, log);
+ // split off rest of the diffs and dissolve the len(1) vec
+ let log = initial.split_off(1);
+ let previous = initial.remove(0).1;
+
+ let mut order = vec![];
+ let (commit_refs, file_refs) = log.into_iter().fold(
+ (BTreeMap::new(), BTreeMap::new()),
+ |(mut cm, mut fm), (cid, current)| {
+ let d = repo
+ .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()));
+ set
+ });
+
+ order.push(cid.clone());
+ fm.insert(cid.clone(), files.clone());
+
+ let commit_u = repo
+ .find_commit(Oid::from_str(cid.as_str()).unwrap())
+ .unwrap();
+ let author_u = commit_u.author();
+ let commit = CommitNode {
+ id: cid.clone(),
+ message: commit_u.message().unwrap().to_owned(),
+ author: format!("{} {}", author_u.name().unwrap(), author_u.email().unwrap()),
+ touches: files,
+ time: author_u.when().seconds(),
+ };
+
+ cm.insert(cid.clone(), commit);
+
+ (cm, fm)
+ },
+ );
+
+ let graph = CommitGraph {
+ order,
+ file_refs,
+ commit_refs,
+ };
+
+ dbg!(graph);
+
+ // let diffs = build_diff_log(&repo, log);
todo!()
}