aboutsummaryrefslogtreecommitdiff
path: root/src/git/log.rs
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2020-06-22 06:23:04 +0200
committerKatharina Fey <kookie@spacekookie.de>2020-06-22 06:23:04 +0200
commite30713b84bc9e66f7a8e8d2f51e953472cac28e4 (patch)
tree3098b1c77a978dcad0c828f57386d1c8999aa26b /src/git/log.rs
parent84a9a0ccee713e26a28ff5e54ea3776085d93b5f (diff)
Committing all the libgit2 progress before throwing it away
I don't think libgit2 is the way forward to make any of this work. There's so much work involved in parsing the git k-v store, and the library itself is essentially of zero help for most of the heavy lifting.
Diffstat (limited to '')
-rw-r--r--src/git/log.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/git/log.rs b/src/git/log.rs
new file mode 100644
index 0000000..dab9e69
--- /dev/null
+++ b/src/git/log.rs
@@ -0,0 +1,61 @@
+//! libgit2 log parsing
+
+use crate::git::{self, tree::FileNode};
+use git2::{Oid, Repository};
+use std::collections::{BTreeMap, BTreeSet};
+
+/// A file-commit referenced graph thing
+///
+/// git is _weird_! It's essentially just a glorified key-value store
+/// and it shows. There's no utilities to figure out how thing are
+/// related, and all the actual graph things in git are sugar on top
+/// of this store.
+///
+/// In order to make sense of anything in a repo we need to quite
+/// 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)]
+pub(crate) struct CommitGraph {
+ order: Vec<String>,
+ file_refs: BTreeMap<String, BTreeSet<String>>,
+ commit_refs: BTreeMap<String, CommitNode>,
+}
+
+pub(crate) struct CommitNode {
+ id: String,
+ author: String,
+ touches: BTreeSet<String>,
+ date: String,
+}
+
+fn build_diff_log(repo: &Repository, 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();
+ let mut v = walker
+ .into_iter()
+ .map(|oid| {
+ let oid = oid.unwrap();
+ repo.find_commit(oid).unwrap()
+ })
+ .collect::<Vec<_>>();
+ v.reverse();
+
+ let log: Vec<_> = v
+ .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())
+ })
+ .collect();
+
+ let diffs = build_diff_log(&repo, log);
+ todo!()
+}