\node[right,xshift=10] (label2256509) at (2256509.east) {\verb!2256509: [py] fixed automatic colors!};
\node[commit, black, fill=black] (6e41ab0) at (0.0,6.0) {};
\node[right,xshift=10] (label6e41ab0) at (6e41ab0.east) {\verb!6e41ab0: [py] fixed order!};
-\node[commit, black, fill=black] (53e02cf) at (0.0,6.5) {};
+\node[commit, blue, fill=blue] (16d4f59) at (0.5,6.5) {};
+\node[right,xshift=10] (label16d4f59) at (16d4f59.east) {\verb!16d4f59: [doc] test!};
+\node[commit, black, fill=black] (53e02cf) at (0.0,7.0) {};
\node[right,xshift=10] (label53e02cf) at (53e02cf.east) {\verb!53e02cf: [doc] test!};
-\node[commit, black, fill=black] (8dde7ec) at (0.0,7.0) {};
+\node[commit, black, fill=black] (8dde7ec) at (0.0,7.5) {};
\node[right,xshift=10] (label8dde7ec) at (8dde7ec.east) {\verb!8dde7ec: [doc] neues Hooks!};
-\node[commit, black, fill=black] (8024ece) at (0.0,7.5) {};
+\node[commit, black, fill=black] (8024ece) at (0.0,8.0) {};
\node[right,xshift=10] (label8024ece) at (8024ece.east) {\verb!8024ece: [doc] hook test!};
-\node[commit, black, fill=black] (7ef61eb) at (0.0,8.0) {};
+\node[commit, black, fill=black] (7ef61eb) at (0.0,8.5) {};
\node[right,xshift=10] (label7ef61eb) at (7ef61eb.east) {\verb!7ef61eb: [doc] hooktest 2!};
-\node[commit, black, fill=black] (d477a13) at (0.0,8.5) {};
-\node[right,xshift=10] (labeld477a13) at (d477a13.east) {\verb!d477a13: [doc] neuer Branch!};
\node[commit, blue, fill=blue] (d2bf877) at (0.5,9.0) {};
\node[right,xshift=10] (labeld2bf877) at (d2bf877.east) {\verb!d2bf877: [py] new git order!};
\node[commit, blue, fill=blue] (6b30984) at (0.5,9.5) {};
\node[right,xshift=10] (label6b30984) at (6b30984.east) {\verb!6b30984: [py] 2new git order!};
-\node[commit, blue, fill=blue] (827f503) at (0.5,10.0) {};
+\node[commit, brown, fill=brown] (feccffc) at (1.0,10.0) {};
+\node[right,xshift=10] (labelfeccffc) at (feccffc.east) {\verb!feccffc: Merge branch 'develop'!};
+\node[commit, brown, fill=brown] (1b6432e) at (1.0,10.5) {};
+\node[right,xshift=10] (label1b6432e) at (1b6432e.east) {\verb!1b6432e: merge successful!};
+\node[commit, blue, fill=blue] (827f503) at (0.5,11.0) {};
\node[right,xshift=10] (label827f503) at (827f503.east) {\verb!827f503: [doc] Features/Bugs [py] reversed changed!};
-\node[commit, blue, fill=blue] (0ee95d1) at (0.5,10.5) {};
+\node[commit, blue, fill=blue] (0ee95d1) at (0.5,11.5) {};
\node[right,xshift=10] (label0ee95d1) at (0ee95d1.east) {\verb!0ee95d1: [doc] Hook test!};
-\node[commit, blue, fill=blue] (0009b09) at (0.5,11.0) {};
+\node[commit, blue, fill=blue] (0009b09) at (0.5,12.0) {};
\node[right,xshift=10] (label0009b09) at (0009b09.east) {\verb!0009b09: [doc] Hook2 test!};
-\node[commit, blue, fill=blue] (494a6ba) at (0.5,11.5) {};
+\node[commit, blue, fill=blue] (494a6ba) at (0.5,12.5) {};
\node[right,xshift=10] (label494a6ba) at (494a6ba.east) {\verb!494a6ba: [doc] Hook2 test!};
-\node[commit, blue, fill=blue] (ddec20f) at (0.5,12.0) {};
+\node[commit, blue, fill=blue] (ddec20f) at (0.5,13.0) {};
\node[right,xshift=10] (labelddec20f) at (ddec20f.east) {\verb!ddec20f: [doc] lsting Hooks!};
-\node[commit, blue, fill=blue] (71f4986) at (0.5,12.5) {};
+\node[commit, brown, fill=brown] (65dae54) at (1.0,13.5) {};
+\node[right,xshift=10] (label65dae54) at (65dae54.east) {\verb!65dae54: Merge branch 'develop'!};
+\node[commit, black, fill=black] (d477a13) at (0.0,14.0) {};
+\node[right,xshift=10] (labeld477a13) at (d477a13.east) {\verb!d477a13: [doc] neuer Branch !};
+\node[commit, blue, fill=blue] (71f4986) at (0.5,14.5) {};
\node[right,xshift=10] (label71f4986) at (71f4986.east) {\verb!71f4986: [py] better color function!};
-\node[commit, black, fill=black] (7c94d50) at (0.0,13.0) {};
+\node[commit, black, fill=black] (7c94d50) at (0.0,15.0) {};
\node[right,xshift=10] (label7c94d50) at (7c94d50.east) {\verb!7c94d50: Merge branch 'develop' into feature/python2!};
-\node[commit, black, fill=black] (52b6561) at (0.0,13.5) {};
+\node[commit, black, fill=black] (52b6561) at (0.0,15.5) {};
\node[right,xshift=10] (label52b6561) at (52b6561.east) {\verb!52b6561: minor PyUpdate Fix Front parsing works basic!};
-\node[commit, black, fill=black] (cc9a3ca) at (0.0,14.0) {};
+\node[commit, black, fill=black] (cc9a3ca) at (0.0,16.0) {};
\node[right,xshift=10] (labelcc9a3ca) at (cc9a3ca.east) {\verb!cc9a3ca: parsing for repo works!};
-\node[commit, black, fill=black] (769f9d1) at (0.0,14.5) {};
+\node[commit, black, fill=black] (769f9d1) at (0.0,16.5) {};
\node[right,xshift=10] (label769f9d1) at (769f9d1.east) {\verb!769f9d1: new Hashing, resolve Parents works!};
-\node[commit, black, fill=black] (a53824c) at (0.0,15.0) {};
+\node[commit, black, fill=black] (a53824c) at (0.0,17.0) {};
\node[right,xshift=10] (labela53824c) at (a53824c.east) {\verb!a53824c: fixed some issues!};
+\node[commit, black, fill=black] (0f95945) at (0.0,17.5) {};
+\node[right,xshift=10] (label0f95945) at (0f95945.east) {\verb!0f95945: . fix for messages!};
+\path[black] (a53824c) to[out=90,in=-90] (0f95945);
\path[black] (769f9d1) to[out=90,in=-90] (a53824c);
\path[black] (cc9a3ca) to[out=90,in=-90] (769f9d1);
\path[black] (52b6561) to[out=90,in=-90] (cc9a3ca);
\path[black] (7c94d50) to[out=90,in=-90] (52b6561);
\path[blue] (71f4986) to[out=90,in=-90] (7c94d50);
+\path[black] (d477a13) to[out=90,in=-90] (7c94d50);
\path[blue] (ddec20f) to[out=90,in=-90] (71f4986);
+\path[blue] (ddec20f) to[out=90,in=-90] (65dae54);
\path[blue] (494a6ba) to[out=90,in=-90] (ddec20f);
\path[blue] (0009b09) to[out=90,in=-90] (494a6ba);
\path[blue] (0ee95d1) to[out=90,in=-90] (0009b09);
\path[blue] (827f503) to[out=90,in=-90] (0ee95d1);
+\path[brown] (1b6432e) to[out=90,in=-90] (65dae54);
+\path[brown] (feccffc) to[out=90,in=-90] (1b6432e);
\path[blue] (6b30984) to[out=90,in=-90] (827f503);
+\path[blue] (6b30984) to[out=90,in=-90] (feccffc);
\path[blue] (d2bf877) to[out=90,in=-90] (6b30984);
-\path[black] (d477a13) to[out=90,in=-90] (7c94d50);
-\path[black] (7ef61eb) to[out=90,in=-90] (d2bf877);
\path[black] (7ef61eb) to[out=90,in=-90] (d477a13);
+\path[black] (7ef61eb) to[out=90,in=-90] (d2bf877);
\path[black] (8024ece) to[out=90,in=-90] (7ef61eb);
\path[black] (8dde7ec) to[out=90,in=-90] (8024ece);
\path[black] (53e02cf) to[out=90,in=-90] (8dde7ec);
+\path[blue] (16d4f59) to[out=90,in=-90] (feccffc);
\path[black] (6e41ab0) to[out=90,in=-90] (53e02cf);
+\path[black] (6e41ab0) to[out=90,in=-90] (16d4f59);
\path[black] (2256509) to[out=90,in=-90] (6e41ab0);
\path[black] (8a5d531) to[out=90,in=-90] (2256509);
\path[black] (7ac7de4) to[out=90,in=-90] (8a5d531);
\path[black] (e5c3cd5) to[out=90,in=-90] (9ebee64);
\path[black] (d78896f) to[out=90,in=-90] (e5c3cd5);
\path[black] (a6f6d74) to[out=90,in=-90] (d78896f);
-\node[branch,right,xshift=10] (feature/python2) at (labela53824c.east) {\lstinline{feature/python2}};
+\node[branch,right,xshift=10] (feature/python2) at (label0f95945.east) {\lstinline{feature/python2}};
+\node[branch,right,xshift=10] (master) at (label65dae54.east) {\lstinline{master}};
+\node[branch,right,xshift=10] (origin/HEAD) at (label65dae54.east) {\lstinline{origin/HEAD}};
+\node[branch,right,xshift=10] (origin/develop) at (label71f4986.east) {\lstinline{origin/develop}};
+\node[branch,right,xshift=10] (origin/feature/python) at (label6b30984.east) {\lstinline{origin/feature/python}};
+\node[branch,right,xshift=10] (origin/feature/python2) at (label769f9d1.east) {\lstinline{origin/feature/python2}};
+\node[branch,right,xshift=10] (origin/master) at (label65dae54.east) {\lstinline{origin/master}};
\end{tikzpicture}
#!/usr/bin/python
+#Author: P. Schaefer
+
from subprocess import check_output
from collections import OrderedDict
from re import compile, match
class Hash:
hashpat7 = compile(r"[a-f0-9]{7}")
hashpat40 = compile(r"[a-f0-9]{40}")
+ def isHash(hash):
+ return Hash.hashpat7.match(hash) or Hash.hashpat40.match(hash)
+
def __init__(self,hash):
- if Hash.hashpat7.match(hash) or Hash.hashpat40.match(hash):
+ if Hash.isHash(hash):
self._hash: str = hash
else:
- raise ValueError('Wrong Hash Format')
+ raise ValueError('Wrong Hash Format: ' + hash)
def hash(self):
return self._hash[0:7]
class Branch:
def __init__(self, line):
- words = line[2:].split(" ")
- self._name = words.pop(0)
- while words[0] == "":
- words.pop(0)
- self._hash = Hash(words.pop(0))
- self._commit = " ".join(words)
+ words = list(filter(lambda x:x!='',line[2:].split(" ")))
+ name = words[0].split('/')
+ if name[0] == 'remotes':
+ self._remote = name[1]
+ self._name = '/'.join(name[2:])
+ else:
+ self._name = '/'.join(name)
+ self._remote = None
+ if Hash.isHash(words[1]):
+ self._hash = Hash(words[1])
+ elif words[1] == '->':
+ self._hash = None
+ self._link = words[2]
+ else:
+ raise ValueError('Not known Branch syntax: ' + words[1])
def hash(self):
return self._hash.hash()
+
+ def name(self):
+ if self._remote:
+ return self._remote + '/' + self._name
+ else:
+ return self._name
- def to_s_long(self):
- print("Name : " + self._name)
- print("Hash : " + self._hash)
- print("Commit: " + VerbClean(self._commit))
+ def export_branch2tikz(self):
+ print("\\node[branch,right,xshift=10] (" + self.name() + ") at (label" + self.hash() + ".east) {\\lstinline{" + self.name() +"}};")
+
+ def __eq__(self,other):
+ return self.name() == other
- def to_s(self):
- print(" ".join({self._name, self._hash, self._commit}))
class Repo:
def __init__(self):
def resolve_parents(self):
for commit in self._commits.values():
for key_p in commit._parents.keys():
-
commit.update_parent(self._commits[key_p])
- def add_branch(self, branch):
- if branch.hash() in self._commits:
- branch._commit = self._commits[branch.hash()]
- self._branches.append(branch)
+ def add_branchlog(self,log):
+ #read all branches
+ branches = []
+ for line in log.split("\n"):
+ if not line == "":
+ branches.append(Branch(line))
+ #use only branches in commitlist
+ for branch in branches:
+ if not branch._hash:
+ branch._hash = branches[branches.index(branch._link)]._hash
+ del branch._link
+ if branch.hash() in self._commits:
+ self._branches.append(branch)
+
def export_to_tikz(self):
print("\\begin{tikzpicture}")
print("\\tikzstyle{commit}=[draw,circle,fill=white,inner sep=0pt,minimum size=5pt]")
print("\\tikzstyle{every path}=[draw]")
print("\\tikzstyle{branch}=[draw,rectangle,rounded corners=3,fill=white,inner sep=2pt,minimum size=5pt]")
+
+ #Draw Commit Info
ypos = 0
ystep = .5
for commit in reversed(self._commits.values()):
- commit.export_to_tikz(ypos)
+ commit.export_commit2tikz(ypos)
ypos = ypos + ystep
+ #Draw Paths
for commit in self._commits.values():
- for child in commit._children.values():
- print("\\path[" + color(commit._node_pos) +"] (" + commit.hash() + ") to[out=90,in=-90] (" + child.hash() + ");")
+ commit.export_path2tikz()
+
+ #Draw Branch Info
for branch in self._branches:
- print("\\node[branch,right,xshift=10] (" + branch._name + ") at (label" + branch.hash() + ".east) {\\lstinline{" + branch._name +"}};")
+ branch.export_branch2tikz()
+
print("\\end{tikzpicture}")
class Commit:
self._message = self._message + "\n" + line[4:]
else:
self._message = line[4:]
+ elif line.replace(' ','') == '' or info[0] == 'Merge':
+ NotImplemented
+ else:
+ raise ValueError('Unkown format: ' + line)
def update_parent (self, child):
self._parents[child.hash()] = child
child._children[self.hash()] = self
- def export_to_tikz(self, ypos):
+ def export_commit2tikz(self, ypos):
print("\\node[commit, " + color(self._node_pos) + ", fill=" + color(self._node_pos) + "] (" + self.hash() + ") at (" + str(.5 * self._node_pos) + "," + str(ypos) + ") {};")
print("\\node[right,xshift=10] (label" + self.hash() + ") at (" + self.hash() + ".east) {\\verb!" + self.hash() + ": " + VerbClean(self._message) + "!};")
+
+ def export_path2tikz(self):
+ for child in self._children.values():
+ print("\\path[" + color(self._node_pos) +"] (" + self.hash() + ") to[out=90,in=-90] (" + child.hash() + ");")
def __eq__(self,other):
return self.hash() == other.hash()
r = Repo()
# extract Commits
-cmd = "git log --graph --parents"
+cmd = "git log --graph --branches --parents"
return_output = check_output(cmd, shell=True, encoding='utf-8')
#print(return_output.split("\n"))
r.add_commitlog(return_output)
# extract Branches
-cmd = "git branch -v" # | cut -b 3-"
+cmd = "git branch -va" # | cut -b 3-"
return_output = check_output(cmd, shell=True, encoding='utf-8')
#print(return_output.split("\n"))
-for line in return_output.split("\n"):
- if not line == "":
- r.add_branch(Branch(line))
+r.add_branchlog(return_output)
r.export_to_tikz()
\ No newline at end of file