diff options
author | Katharina Fey <kookie@spacekookie.de> | 2020-06-22 06:23:04 +0200 |
---|---|---|
committer | Katharina Fey <kookie@spacekookie.de> | 2020-06-22 06:23:04 +0200 |
commit | e30713b84bc9e66f7a8e8d2f51e953472cac28e4 (patch) | |
tree | 3098b1c77a978dcad0c828f57386d1c8999aa26b /src/git/log.rs | |
parent | 84a9a0ccee713e26a28ff5e54ea3776085d93b5f (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.rs | 61 |
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!() +} |