Skip to content

Commit 925ee3e

Browse files
authored
Merge pull request #3 from yeger00/git-graph-log-support
adding log support to git graph
2 parents ce0dbd2 + 81b848b commit 925ee3e

File tree

5 files changed

+115
-48
lines changed

5 files changed

+115
-48
lines changed

README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,22 @@ Utilities to view diff between graphs
33

44
# Getting starget
55

6-
## Intall prerequists
6+
## Install prerequisites
77
1. graph-easy
8-
1. `pip install -r requirements.txt`
8+
9+
## Install
10+
```
11+
git clone https://github.com/yeger00/graph-diff
12+
pip install -e .
13+
```
914

1015
## Generate and view diff
1116
```
1217
cat samples/before.dot | graph-easy --as boxart
1318
cat samples/after.dot | graph-easy --as boxart
14-
python generate-diff-graph.py samples/before.dot samples/after.dot ./diff.dot
15-
cat diff.dot | ./diff-graph-color
19+
python -m graphdiff samples/before.dot samples/after.dot ./diff.dot
20+
cat ./diff.dot | ./diff-graph-color
1621
```
1722

23+
# git-diff
24+
TODO

git-graph

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/usr/bin/env python
2+
3+
"""
4+
Utility to show git graph diff.
5+
"""
6+
7+
import sys
8+
import subprocess
9+
import os
10+
import pydot
11+
import git
12+
import graphdiff
13+
14+
15+
DIR_PATH = os.path.dirname(os.path.realpath(__file__))
16+
COLOR_SCRIPT_PATH = os.path.join(DIR_PATH, "diff-graph-color")
17+
18+
19+
def get_diff_for_file(repo, path):
20+
"""
21+
Return the diff between the current status of the file and the head.
22+
"""
23+
hcommit = repo.head.commit
24+
for diff in hcommit.diff(None):
25+
if diff.a_path == path or diff.b_path == path:
26+
return diff
27+
return None
28+
29+
30+
def get_path_commit_diffs(repo, path):
31+
"""
32+
This function returns a generator which iterates through all commits of
33+
the repository located in the given path for the given branch. It yields
34+
file diff information to show a timeseries of file changes.
35+
"""
36+
for commit in repo.iter_commits():
37+
if commit.parents:
38+
all_diffs = commit.diff(commit.parents[0])
39+
else:
40+
all_diffs = commit.diff(None)
41+
42+
for diff in all_diffs:
43+
if diff.a_path == path or diff.b_path == path:
44+
yield commit, diff
45+
46+
47+
def print_graph(graph):
48+
"""
49+
Print the given graph.
50+
"""
51+
pydot_graph = graphdiff.to_dot(graph)
52+
proc = subprocess.Popen([COLOR_SCRIPT_PATH], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
53+
proc.stdin.write(pydot_graph.to_string().encode("utf-8"))
54+
out, _ = proc.communicate()
55+
print(out.decode("utf-8"))
56+
57+
58+
def load_graph_from_blob(blob):
59+
"""
60+
Loads and returns the graph from the given diff blob.
61+
"""
62+
blob_bytes = blob.data_stream.read()
63+
# TODO: handle more than one graph
64+
blob_dot_graph = pydot.graph_from_dot_data(blob_bytes.decode("utf-8"))[0]
65+
return graphdiff.from_dot(blob_dot_graph)
66+
67+
68+
def main(mode, path):
69+
"""
70+
Main function of the module
71+
"""
72+
# Create the repository, raises an error if it isn't one.
73+
repo = git.Repo("./")
74+
75+
if mode == "diff":
76+
diff = get_diff_for_file(repo, path)
77+
if diff:
78+
a_graph = graphdiff.Graph()
79+
if diff.a_blob:
80+
a_graph = load_graph_from_blob(diff.a_blob)
81+
b_graph = graphdiff.from_dot(pydot.graph_from_dot_file(path)[0])
82+
print_graph(graphdiff.generate_diff_graph(a_graph, b_graph))
83+
elif mode == "log":
84+
for commit, diff in get_path_commit_diffs(repo, path):
85+
a_graph = graphdiff.Graph()
86+
if diff.a_blob:
87+
a_graph = load_graph_from_blob(diff.a_blob)
88+
89+
b_graph = graphdiff.Graph()
90+
if diff.b_blob:
91+
b_graph = load_graph_from_blob(diff.b_blob)
92+
print("commit {}".format(commit.hexsha))
93+
print("Author: {} <{}>".format(commit.author.name, commit.author.email))
94+
print("Date: {}".format(commit.authored_datetime.strftime("%a %b %d %H:%M:%S %Y")))
95+
print()
96+
print_graph(graphdiff.generate_diff_graph(b_graph, a_graph))
97+
98+
99+
if __name__ == "__main__":
100+
main(sys.argv[1], sys.argv[2])

git-graph-diff

Lines changed: 0 additions & 43 deletions
This file was deleted.

graphdiff/graphdiff.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ def from_dot(pydot_graph):
113113

114114
for edge in pydot_graph.get_edges():
115115
graph.edges.add(Edge(edge.get_source(), edge.get_destination()))
116+
graph.nodes.add(edge.get_source())
117+
graph.nodes.add(edge.get_destination())
116118
return graph
117119

118120

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@ def run_tests(self):
2222

2323
setup(
2424
name="graphdiff",
25-
version="0.0.0",
25+
version="0.0.1",
2626
author="Avi Yeger",
2727
author_email="yeger00@gmail.com",
2828
description="",
2929
long_description=long_description,
3030
long_description_content_type="text/markdown",
3131
url="https://github.com/yeger00/",
3232
packages=find_packages(),
33+
install_requires=["pydot"],
3334
tests_require=["pytest", "pytest_mock"],
3435
cmdclass={"test": PyTest},
3536
)

0 commit comments

Comments
 (0)