Code forensics  0.1
Generate historical information about code changes
repo_graph.hpp
Go to the documentation of this file.
1 #include <boost/graph/adjacency_list.hpp>
2 #include <unordered_map>
3 
4 #include "generator.hpp"
5 #include "git_interface.hpp"
6 
7 namespace bg {
8 using boost::add_edge;
9 using boost::add_vertex;
10 using boost::in_degree;
11 using boost::in_edges;
12 using boost::num_vertices;
13 using boost::out_degree;
14 using boost::out_edges;
15 using boost::source;
16 using boost::target;
17 using boost::vertices;
18 }; // namespace bg
19 
20 struct CommitInfo {
21  git_oid oid;
22 };
23 
24 struct CommitEdge {
25  bool is_main;
26 };
27 
28 
29 struct CommitGraph {
30  using Graph = boost::adjacency_list<
31  boost::vecS,
32  boost::vecS,
33  boost::bidirectionalS,
34  CommitInfo,
36 
37  using GraphTraits = boost::graph_traits<Graph>;
38  using VDesc = GraphTraits::vertex_descriptor;
39  using EDesc = GraphTraits::edge_descriptor;
40 
42 
43  std::unordered_map<git_oid, VDesc> rev_map;
44  std::unordered_set<VDesc> main_set;
45 
46 
47  public:
48  std::vector<VDesc> main_path;
49 
50  inline int in_degree(VDesc v) const { return bg::in_degree(v, g); }
51  inline int out_degree(VDesc v) const { return bg::out_degree(v, g); }
52  inline CommitInfo& operator[](VDesc v) { return g[v]; }
53  inline CommitEdge& operator[](EDesc e) { return g[e]; }
54  inline VDesc operator[](CR<git_oid> oid) { return get_desc(oid); }
55  inline VDesc source(EDesc e) const { return bg::source(e, g); }
56  inline VDesc target(EDesc e) const { return bg::target(e, g); }
57  inline bool is_merge(VDesc v) const { return 1 < in_degree(v); }
58 
59  inline bool is_main(VDesc v) const {
60  return main_set.find(v) != main_set.end();
61  }
62 
63  inline Opt<VDesc> get_base(VDesc v) const {
64  for (auto in : parent_commits(v)) {
65  if (g[in].is_main) { return source(in); }
66  }
67 
68  return Opt<VDesc>{};
69  }
70 
71  inline generator<EDesc> parent_commits(VDesc v) const {
72  for (auto [begin, end] = bg::in_edges(v, g); begin != end;
73  ++begin) {
74  co_yield *begin;
75  }
76  }
77 
78  inline generator<EDesc> next_commits(VDesc v) const {
79  for (auto [begin, end] = bg::out_edges(v, g); begin != end;
80  ++begin) {
81  co_yield *begin;
82  }
83  }
84 
85  inline generator<VDesc> commits() const {
86  for (auto [begin, end] = bg::vertices(g); begin != end; ++begin) {
87  co_yield *begin;
88  }
89  }
90 
96  inline generator<Pair<VDesc, Opt<VDesc>>> commit_pairs() const {
97  std::unordered_set<VDesc> tried;
98  for (auto v : commits()) {
99  if (tried.find(v) == tried.end()) {
100  tried.insert(v);
101  co_yield {v, get_base(v)};
102  }
103  }
104  }
105 
106 
107  VDesc get_desc(CR<git_oid> oid);
108  CommitGraph(git_repository* repo);
109 };
CommitGraph::is_merge
bool is_merge(VDesc v) const
Definition: repo_graph.hpp:57
CommitEdge::is_main
bool is_main
Definition: repo_graph.hpp:25
git_interface.hpp
CommitGraph::operator[]
CommitEdge & operator[](EDesc e)
Definition: repo_graph.hpp:53
CommitInfo::oid
git_oid oid
Definition: repo_graph.hpp:21
bg
Definition: repo_graph.hpp:7
CommitGraph::commits
generator< VDesc > commits() const
Definition: repo_graph.hpp:85
CommitGraph::out_degree
int out_degree(VDesc v) const
Definition: repo_graph.hpp:51
CommitEdge
Definition: repo_graph.hpp:24
CommitGraph::Graph
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, CommitInfo, CommitEdge > Graph
Definition: repo_graph.hpp:35
CommitGraph::CommitGraph
CommitGraph(git_repository *repo)
Definition: repo_graph.cpp:3
CommitGraph::is_main
bool is_main(VDesc v) const
Definition: repo_graph.hpp:59
CommitGraph::in_degree
int in_degree(VDesc v) const
Definition: repo_graph.hpp:50
CommitGraph::VDesc
GraphTraits::vertex_descriptor VDesc
Definition: repo_graph.hpp:38
CommitGraph::g
Graph g
Definition: repo_graph.hpp:41
CommitGraph::get_desc
VDesc get_desc(CR< git_oid > oid)
Definition: repo_graph.cpp:66
CommitGraph::parent_commits
generator< EDesc > parent_commits(VDesc v) const
Definition: repo_graph.hpp:71
CommitGraph
Definition: repo_graph.hpp:29
CommitGraph::main_set
std::unordered_set< VDesc > main_set
Definition: repo_graph.hpp:44
CommitInfo
Definition: repo_graph.hpp:20
CommitGraph::GraphTraits
boost::graph_traits< Graph > GraphTraits
Definition: repo_graph.hpp:37
CommitGraph::operator[]
CommitInfo & operator[](VDesc v)
Definition: repo_graph.hpp:52
CommitGraph::commit_pairs
generator< Pair< VDesc, Opt< VDesc > > > commit_pairs() const
iterate over pairs commit-base (in this order). Merge commits are also included in the iteration resu...
Definition: repo_graph.hpp:96
CommitGraph::EDesc
GraphTraits::edge_descriptor EDesc
Definition: repo_graph.hpp:39
CommitGraph::get_base
Opt< VDesc > get_base(VDesc v) const
Definition: repo_graph.hpp:63
CommitGraph::rev_map
std::unordered_map< git_oid, VDesc > rev_map
Definition: repo_graph.hpp:43
CommitGraph::operator[]
VDesc operator[](CR< git_oid > oid)
Definition: repo_graph.hpp:54
CommitGraph::target
VDesc target(EDesc e) const
Definition: repo_graph.hpp:56
CommitGraph::next_commits
generator< EDesc > next_commits(VDesc v) const
Definition: repo_graph.hpp:78
CommitGraph::main_path
std::vector< VDesc > main_path
Definition: repo_graph.hpp:48
CommitGraph::source
VDesc source(EDesc e) const
Definition: repo_graph.hpp:55