aboutsummaryrefslogtreecommitdiff
path: root/src/git/log.rs
blob: dab9e69ecb54f6120322c5fb6eb75d9c9d179f5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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!()
}