mirror of
https://github.com/correl/correl.github.io.git
synced 2024-12-28 19:19:17 +00:00
2000 lines
158 KiB
HTML
2000 lines
158 KiB
HTML
---
|
|
title: Drawing Git Graphs with Graphviz and Org-Mode
|
|
author: Correl Roush
|
|
tags: emacs org-mode git graphviz
|
|
---
|
|
<style type="text/css">
|
|
svg text {
|
|
fill: white;
|
|
}
|
|
svg path,
|
|
svg polygon,
|
|
svg ellipse {
|
|
stroke: white;
|
|
}
|
|
</style>
|
|
|
|
<p>
|
|
Digging through Derek Feichtinger's <a href="https://github.com/dfeich/org-babel-examples">org-babel examples</a> (which I came
|
|
across via <a href="http://irreal.org/blog/?p=4162">irreal.org</a>), I found he had some great examples of
|
|
displaying git-style graphs using graphviz. I thought it'd be a fun
|
|
exercise to generate my own graphs based on his graphviz source using
|
|
elisp, and point it at actual git repos.
|
|
</p>
|
|
|
|
<div id="outline-container-sec-1" class="outline-2">
|
|
<h2 id="sec-1">Getting Started</h2>
|
|
<div class="outline-text-2" id="text-1">
|
|
<p>
|
|
I started out with the goal of building a simple graph showing a
|
|
mainline branch and a topic branch forked from it and eventually
|
|
merged back in.
|
|
</p>
|
|
|
|
<p>
|
|
Using Derek's example as a template, I described 5 commits on a master
|
|
branch, plus two on a topic branch.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-dot">digraph <span style="color: #268bd2;">G</span> {
|
|
<span style="color: #268bd2;">rankdir=</span><span style="color: #2aa198;">"LR"</span>;
|
|
<span style="color: #268bd2;">bgcolor=</span><span style="color: #2aa198;">"transparent"</span>;
|
|
node[<span style="color: #268bd2;">width=</span>0.15, <span style="color: #268bd2;">height=</span>0.15, <span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">point</span>];
|
|
edge[<span style="color: #268bd2;">weight=</span>2, <span style="color: #268bd2;">arrowhead=</span><span style="color: #268bd2; font-weight: bold;">none</span>];
|
|
node[<span style="color: #268bd2;">group=</span>master];
|
|
1 -> 2 -> 3 -> 4 -> 5;
|
|
node[<span style="color: #268bd2;">group=</span>branch];
|
|
2 -> 6 -> 7 -> 4;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The resulting image looks like this:
|
|
</p>
|
|
|
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
-->
|
|
<!-- Title: G Pages: 1 -->
|
|
<svg width="253pt" height="52pt"
|
|
viewBox="0.00 0.00 252.80 51.80" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 47.8)">
|
|
<title>G</title>
|
|
<!-- 1 -->
|
|
<g id="node1" class="node"><title>1</title>
|
|
<ellipse fill="black" stroke="black" cx="5.4" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2 -->
|
|
<g id="node2" class="node"><title>2</title>
|
|
<ellipse fill="black" stroke="black" cx="52.2" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 1->2 -->
|
|
<g id="edge1" class="edge"><title>1->2</title>
|
|
<path fill="none" stroke="black" d="M10.8594,-38.4C19.4466,-38.4 38.1856,-38.4 46.7587,-38.4"/>
|
|
</g>
|
|
<!-- 3 -->
|
|
<g id="node3" class="node"><title>3</title>
|
|
<ellipse fill="black" stroke="black" cx="145.8" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->3 -->
|
|
<g id="edge2" class="edge"><title>2->3</title>
|
|
<path fill="none" stroke="black" d="M57.6181,-38.4C73.0565,-38.4 124.509,-38.4 140.21,-38.4"/>
|
|
</g>
|
|
<!-- 6 -->
|
|
<g id="node6" class="node"><title>6</title>
|
|
<ellipse fill="black" stroke="black" cx="99" cy="-5.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->6 -->
|
|
<g id="edge5" class="edge"><title>2->6</title>
|
|
<path fill="none" stroke="black" d="M57.0196,-35.5864C65.4836,-29.3518 85.7351,-14.4344 94.19,-8.20644"/>
|
|
</g>
|
|
<!-- 4 -->
|
|
<g id="node4" class="node"><title>4</title>
|
|
<ellipse fill="black" stroke="black" cx="192.6" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 3->4 -->
|
|
<g id="edge3" class="edge"><title>3->4</title>
|
|
<path fill="none" stroke="black" d="M151.259,-38.4C159.847,-38.4 178.586,-38.4 187.159,-38.4"/>
|
|
</g>
|
|
<!-- 5 -->
|
|
<g id="node5" class="node"><title>5</title>
|
|
<ellipse fill="black" stroke="black" cx="239.4" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 4->5 -->
|
|
<g id="edge4" class="edge"><title>4->5</title>
|
|
<path fill="none" stroke="black" d="M198.059,-38.4C206.647,-38.4 225.386,-38.4 233.959,-38.4"/>
|
|
</g>
|
|
<!-- 7 -->
|
|
<g id="node7" class="node"><title>7</title>
|
|
<ellipse fill="black" stroke="black" cx="145.8" cy="-5.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 6->7 -->
|
|
<g id="edge6" class="edge"><title>6->7</title>
|
|
<path fill="none" stroke="black" d="M104.459,-5.4C113.047,-5.4 131.786,-5.4 140.359,-5.4"/>
|
|
</g>
|
|
<!-- 7->4 -->
|
|
<g id="edge7" class="edge"><title>7->4</title>
|
|
<path fill="none" stroke="black" d="M150.62,-8.21356C159.084,-14.4482 179.335,-29.3656 187.79,-35.5936"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-1-1" class="outline-3">
|
|
<h3 id="sec-1-1">Designing the Data Structure</h3>
|
|
<div class="outline-text-3" id="text-1-1">
|
|
<p>
|
|
The first thing I needed to do was describe my data structure. Leaning
|
|
on my experiences reading and working through <a href="https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CB8QFjAA&url=https%253A%252F%252Fmitpress.mit.edu%252Fsicp%252F&ei=lH6gVau5OIGR-AG8j7yACQ&usg=AFQjCNHTCXQK7qN-kYibdy_MqRBWxlr8og&sig2=Lu9WIhyuTJS92e8hxne0Aw&bvm=bv.97653015,d.cWw">SICP</a>, I got to work
|
|
building a constructor function, and several accessors.
|
|
</p>
|
|
|
|
<p>
|
|
I decided to represent each node on a graph with an id, a list of
|
|
parent ids, and a group which will correspond to the branch on the
|
|
graph the commit belongs to.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/make-node</span> <span style="color: #b58900;">(</span><span style="color: #b6a0e0;">id</span> <span style="color: #b58900;">&optional</span> <span style="color: #a6bb99;">parents</span> <span style="color: #a7aac0;">group</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #b3c0a7;">list</span> <span style="color: #b6a0e0;">id</span> <span style="color: #a6bb99;">parents</span> <span style="color: #a7aac0;">group</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/node-id</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #9999bb;">nth</span> <span style="color: #a7aac0;">0</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/node-parents</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #9999bb;">nth</span> <span style="color: #9999bb;">1</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/node-group</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #9999bb;">nth</span> <span style="color: #a6bb99;">2</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-1-2" class="outline-3">
|
|
<h3 id="sec-1-2">Converting the structure to Graphviz</h3>
|
|
<div class="outline-text-3" id="text-1-2">
|
|
<p>
|
|
Now that I had my data structures sorted out, it was time to step
|
|
through them and generate the graphviz source that'd give me the
|
|
nice-looking graphs I was after.
|
|
</p>
|
|
|
|
<p>
|
|
The graph is constructed using the example above as a template. The
|
|
nodes are defined first, followed by the edges between them.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/to-graphviz"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz</span> <span style="color: #b58900;">(</span><span style="color: #b6a0e0;">id</span> <span style="color: #e0d0a0;">nodes</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a7c0b9;">string-join</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #b3c0a7;">list</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #c0a7bd;">concat</span> <span style="color: #2aa198;">"digraph "</span> <span style="color: #b6a0e0;">id</span> <span style="color: #2aa198;">" {"</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #2aa198;">"bgcolor=\"transparent\";"</span>
|
|
<span style="color: #2aa198;">"rankdir=\"LR\";"</span>
|
|
<span style="color: #2aa198;">"node[width=0.15,height=0.15,shape=point,fontsize=8.0];"</span>
|
|
<span style="color: #2aa198;">"edge[weight=2,arrowhead=none];"</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a7c0b9;">string-join</span>
|
|
<span style="color: #859900;">(</span><span style="color: #859900; font-weight: bold;">-map</span> #'<span style="color: #bb99b4;">git-graph/to-graphviz-node</span> <span style="color: #e0d0a0;">nodes</span><span style="color: #859900;">)</span>
|
|
<span style="color: #2aa198;">"\n"</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a7c0b9;">string-join</span>
|
|
<span style="color: #859900;">(</span><span style="color: #859900; font-weight: bold;">-uniq</span> <span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">-flatten</span> <span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">-map</span> #'<span style="color: #9999bb;">git-graph/to-graphviz-edges</span> <span style="color: #e0d0a0;">nodes</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span>
|
|
<span style="color: #2aa198;">"\n"</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #2aa198;">"}"</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #2aa198;">"\n"</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
For the sake of readability, I'll format the output:
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/to-graphviz"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-pretty</span> <span style="color: #b58900;">(</span><span style="color: #b6a0e0;">id</span> <span style="color: #e0d0a0;">nodes</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">with-temp-buffer</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #a7aac0;">graphviz-dot-mode</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #a7c0b9;">insert</span> <span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">git-graph/to-graphviz</span> <span style="color: #b6a0e0;">id</span> <span style="color: #e0d0a0;">nodes</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #a6bb99;">indent-region</span> <span style="color: #6c71c4;">(</span><span style="color: #99bbb4;">point-min</span><span style="color: #6c71c4;">)</span> <span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">point-max</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">buffer-string</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
Each node is built, setting its group attribute when applicable.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-node</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">let</span> <span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #c0afa7;">node-id</span> <span style="color: #859900;">(</span><span style="color: #c0afa7;">git-graph/to-graphviz-node-id</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #e0d0a0;">git-graph/node-id</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #c0a7bd;">concat</span> <span style="color: #c0afa7;">node-id</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #859900; font-weight: bold;">--if-let</span> <span style="color: #859900;">(</span><span style="color: #b6a0e0;">git-graph/node-group</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #c0a7bd;">concat</span> <span style="color: #2aa198;">"[group=\""</span> <span style="color: #268bd2;">it</span> <span style="color: #2aa198;">"\"]"</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #2aa198;">";"</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Graphviz node identifiers are quoted to avoid running into issues with
|
|
spaces or other special characters.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/to-graphviz-nodes"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-node-id</span> <span style="color: #b58900;">(</span><span style="color: #b6a0e0;">id</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a0d6e0;">format</span> <span style="color: #2aa198;">"\"%s\""</span> <span style="color: #b6a0e0;">id</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
For each node, an edge is built connecting the node to each of its
|
|
parents.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/to-graphviz-edges"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-edges</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">let</span> <span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #c0afa7;">node-id</span> <span style="color: #859900;">(</span><span style="color: #e0d0a0;">git-graph/node-id</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">parents</span> <span style="color: #859900;">(</span><span style="color: #a7c0b9;">git-graph/node-parents</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">-map</span> <span style="color: #6c71c4;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #859900;">(</span><span style="color: #a7c0b9;">parent</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #b3c0a7;">git-graph/to-graphviz-edge</span> <span style="color: #c0afa7;">node-id</span> <span style="color: #a7c0b9;">parent</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #a6bb99;">parents</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-edge</span> <span style="color: #b58900;">(</span><span style="color: #a3e0a0;">from</span> <span style="color: #e0a0bc;">to</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #c0a7bd;">concat</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #c0afa7;">git-graph/to-graphviz-node-id</span> <span style="color: #e0a0bc;">to</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #2aa198;">" -> "</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #c0afa7;">git-graph/to-graphviz-node-id</span> <span style="color: #a3e0a0;">from</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #2aa198;">";"</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
With that done, the simple graph above could be generated with the
|
|
following code:
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-example"><span style="color: #2aa198;">(</span><span style="color: #b6a0e0;">git-graph/to-graphviz-pretty</span>
|
|
<span style="color: #2aa198;">"example"</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #b3c0a7;">list</span> <span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #9999bb;">1</span> <span style="color: #bb99b4;">nil</span> <span style="color: #2aa198;">"master"</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a6bb99;">2</span> '<span style="color: #6c71c4;">(</span><span style="color: #9999bb;">1</span><span style="color: #6c71c4;">)</span> <span style="color: #2aa198;">"master"</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #e0a0bc;">3</span> '<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">2</span><span style="color: #6c71c4;">)</span> <span style="color: #2aa198;">"master"</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a0d6e0;">4</span> '<span style="color: #6c71c4;">(</span><span style="color: #e0a0bc;">3</span> <span style="color: #e0a0bc;">7</span><span style="color: #6c71c4;">)</span> <span style="color: #2aa198;">"master"</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a3e0a0;">5</span> '<span style="color: #6c71c4;">(</span><span style="color: #a0d6e0;">4</span><span style="color: #6c71c4;">)</span> <span style="color: #2aa198;">"master"</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a3e0a0;">6</span> '<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">2</span><span style="color: #6c71c4;">)</span> <span style="color: #2aa198;">"branch"</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #e0a0bc;">7</span> '<span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">6</span><span style="color: #6c71c4;">)</span> <span style="color: #2aa198;">"branch"</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Which generates the following graphviz source:
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-dot">digraph <span style="color: #268bd2;">example</span> {
|
|
<span style="color: #268bd2;">bgcolor=</span><span style="color: #2aa198;">"transparent"</span>;
|
|
<span style="color: #268bd2;">rankdir=</span><span style="color: #2aa198;">"LR"</span>;
|
|
node[<span style="color: #268bd2;">width=</span>0.15,<span style="color: #268bd2;">height=</span>0.15,<span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">point</span>,<span style="color: #268bd2;">fontsize=</span>8.0];
|
|
edge[<span style="color: #268bd2;">weight=</span>2,<span style="color: #268bd2;">arrowhead=</span><span style="color: #268bd2; font-weight: bold;">none</span>];
|
|
<span style="color: #2aa198;">"1"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"2"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"3"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"4"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"5"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"6"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"branch"</span>];
|
|
<span style="color: #2aa198;">"7"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"branch"</span>];
|
|
<span style="color: #2aa198;">"1"</span> -> <span style="color: #2aa198;">"2"</span>;
|
|
<span style="color: #2aa198;">"2"</span> -> <span style="color: #2aa198;">"3"</span>;
|
|
<span style="color: #2aa198;">"3"</span> -> <span style="color: #2aa198;">"4"</span>;
|
|
<span style="color: #2aa198;">"7"</span> -> <span style="color: #2aa198;">"4"</span>;
|
|
<span style="color: #2aa198;">"4"</span> -> <span style="color: #2aa198;">"5"</span>;
|
|
<span style="color: #2aa198;">"2"</span> -> <span style="color: #2aa198;">"6"</span>;
|
|
<span style="color: #2aa198;">"6"</span> -> <span style="color: #2aa198;">"7"</span>;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The generated image matches the example exactly:
|
|
</p>
|
|
|
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
-->
|
|
<!-- Title: example Pages: 1 -->
|
|
<svg width="253pt" height="52pt"
|
|
viewBox="0.00 0.00 252.80 51.80" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 47.8)">
|
|
<title>example</title>
|
|
<!-- 1 -->
|
|
<g id="node1" class="node"><title>1</title>
|
|
<ellipse fill="black" stroke="black" cx="5.4" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2 -->
|
|
<g id="node2" class="node"><title>2</title>
|
|
<ellipse fill="black" stroke="black" cx="52.2" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 1->2 -->
|
|
<g id="edge1" class="edge"><title>1->2</title>
|
|
<path fill="none" stroke="black" d="M10.8594,-38.4C19.4466,-38.4 38.1856,-38.4 46.7587,-38.4"/>
|
|
</g>
|
|
<!-- 3 -->
|
|
<g id="node3" class="node"><title>3</title>
|
|
<ellipse fill="black" stroke="black" cx="145.8" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->3 -->
|
|
<g id="edge2" class="edge"><title>2->3</title>
|
|
<path fill="none" stroke="black" d="M57.6181,-38.4C73.0565,-38.4 124.509,-38.4 140.21,-38.4"/>
|
|
</g>
|
|
<!-- 6 -->
|
|
<g id="node6" class="node"><title>6</title>
|
|
<ellipse fill="black" stroke="black" cx="99" cy="-5.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->6 -->
|
|
<g id="edge6" class="edge"><title>2->6</title>
|
|
<path fill="none" stroke="black" d="M57.0196,-35.5864C65.4836,-29.3518 85.7351,-14.4344 94.19,-8.20644"/>
|
|
</g>
|
|
<!-- 4 -->
|
|
<g id="node4" class="node"><title>4</title>
|
|
<ellipse fill="black" stroke="black" cx="192.6" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 3->4 -->
|
|
<g id="edge3" class="edge"><title>3->4</title>
|
|
<path fill="none" stroke="black" d="M151.259,-38.4C159.847,-38.4 178.586,-38.4 187.159,-38.4"/>
|
|
</g>
|
|
<!-- 5 -->
|
|
<g id="node5" class="node"><title>5</title>
|
|
<ellipse fill="black" stroke="black" cx="239.4" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 4->5 -->
|
|
<g id="edge5" class="edge"><title>4->5</title>
|
|
<path fill="none" stroke="black" d="M198.059,-38.4C206.647,-38.4 225.386,-38.4 233.959,-38.4"/>
|
|
</g>
|
|
<!-- 7 -->
|
|
<g id="node7" class="node"><title>7</title>
|
|
<ellipse fill="black" stroke="black" cx="145.8" cy="-5.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 6->7 -->
|
|
<g id="edge7" class="edge"><title>6->7</title>
|
|
<path fill="none" stroke="black" d="M104.459,-5.4C113.047,-5.4 131.786,-5.4 140.359,-5.4"/>
|
|
</g>
|
|
<!-- 7->4 -->
|
|
<g id="edge4" class="edge"><title>7->4</title>
|
|
<path fill="none" stroke="black" d="M150.62,-8.21356C159.084,-14.4482 179.335,-29.3656 187.79,-35.5936"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-2" class="outline-2">
|
|
<h2 id="sec-2">Adding Labels</h2>
|
|
<div class="outline-text-2" id="text-2">
|
|
<p>
|
|
The next thing my graph needed was a way of labeling nodes. Rather
|
|
than trying to figure out some way of attaching a separate label to a
|
|
node, I decided to simply draw a labeled node as a box with text.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-dot">digraph <span style="color: #268bd2;">G</span> {
|
|
<span style="color: #268bd2;">rankdir=</span><span style="color: #2aa198;">"LR"</span>;
|
|
<span style="color: #268bd2;">bgcolor=</span><span style="color: #2aa198;">"transparent"</span>;
|
|
node[<span style="color: #268bd2;">width=</span>0.15, <span style="color: #268bd2;">height=</span>0.15, <span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">point</span>,<span style="color: #268bd2;">fontsize=</span>8.0];
|
|
edge[<span style="color: #268bd2;">weight=</span>2, <span style="color: #268bd2;">arrowhead=</span><span style="color: #268bd2; font-weight: bold;">none</span>];
|
|
node[<span style="color: #268bd2;">group=</span>main];
|
|
1 -> 2 -> 3 -> 4 -> 5;
|
|
5[<span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">box</span>,<span style="color: #268bd2;">label=</span>master];
|
|
node[<span style="color: #268bd2;">group=</span>branch1];
|
|
2 -> 6 -> 7 -> 4;
|
|
7[<span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">box</span>,<span style="color: #268bd2;">label=</span>branch];
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
-->
|
|
<!-- Title: G Pages: 1 -->
|
|
<svg width="307pt" height="58pt"
|
|
viewBox="0.00 0.00 307.20 58.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 54)">
|
|
<title>G</title>
|
|
<!-- 1 -->
|
|
<g id="node1" class="node"><title>1</title>
|
|
<ellipse fill="black" stroke="black" cx="5.4" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2 -->
|
|
<g id="node2" class="node"><title>2</title>
|
|
<ellipse fill="black" stroke="black" cx="52.2" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 1->2 -->
|
|
<g id="edge1" class="edge"><title>1->2</title>
|
|
<path fill="none" stroke="black" d="M10.8594,-41.5C19.4466,-41.5 38.1856,-41.5 46.7587,-41.5"/>
|
|
</g>
|
|
<!-- 3 -->
|
|
<g id="node3" class="node"><title>3</title>
|
|
<ellipse fill="black" stroke="black" cx="159.4" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->3 -->
|
|
<g id="edge2" class="edge"><title>2->3</title>
|
|
<path fill="none" stroke="black" d="M57.7203,-41.5C74.8673,-41.5 135.82,-41.5 153.537,-41.5"/>
|
|
</g>
|
|
<!-- 6 -->
|
|
<g id="node6" class="node"><title>6</title>
|
|
<ellipse fill="black" stroke="black" cx="99" cy="-8.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->6 -->
|
|
<g id="edge5" class="edge"><title>2->6</title>
|
|
<path fill="none" stroke="black" d="M57.0196,-38.6864C65.4836,-32.4518 85.7351,-17.5344 94.19,-11.3064"/>
|
|
</g>
|
|
<!-- 4 -->
|
|
<g id="node4" class="node"><title>4</title>
|
|
<ellipse fill="black" stroke="black" cx="219.8" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 3->4 -->
|
|
<g id="edge3" class="edge"><title>3->4</title>
|
|
<path fill="none" stroke="black" d="M164.983,-41.5C175.953,-41.5 203.614,-41.5 214.399,-41.5"/>
|
|
</g>
|
|
<!-- 5 -->
|
|
<g id="node5" class="node"><title>5</title>
|
|
<polygon fill="none" stroke="black" points="299.2,-50 261.2,-50 261.2,-33 299.2,-33 299.2,-50"/>
|
|
<text text-anchor="middle" x="280.2" y="-39.6" font-family="Times,serif" font-size="8.00">master</text>
|
|
</g>
|
|
<!-- 4->5 -->
|
|
<g id="edge4" class="edge"><title>4->5</title>
|
|
<path fill="none" stroke="black" d="M225.383,-41.5C232.965,-41.5 248.521,-41.5 260.967,-41.5"/>
|
|
</g>
|
|
<!-- 7 -->
|
|
<g id="node7" class="node"><title>7</title>
|
|
<polygon fill="none" stroke="black" points="178.4,-17 140.4,-17 140.4,-0 178.4,-0 178.4,-17"/>
|
|
<text text-anchor="middle" x="159.4" y="-6.6" font-family="Times,serif" font-size="8.00">branch</text>
|
|
</g>
|
|
<!-- 6->7 -->
|
|
<g id="edge6" class="edge"><title>6->7</title>
|
|
<path fill="none" stroke="black" d="M104.583,-8.5C112.165,-8.5 127.721,-8.5 140.167,-8.5"/>
|
|
</g>
|
|
<!-- 7->4 -->
|
|
<g id="edge7" class="edge"><title>7->4</title>
|
|
<path fill="none" stroke="black" d="M175.744,-17.1704C188.721,-24.5034 206.452,-34.5223 214.506,-39.0734"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-2-1" class="outline-3">
|
|
<h3 id="sec-2-1">Updating the Data Structure</h3>
|
|
<div class="outline-text-3" id="text-2-1">
|
|
<p>
|
|
I updated my data structure to support an optional label applied to a
|
|
node. I opted to store it in an associative list alongside the group.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/structure"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/make-node</span> <span style="color: #b58900;">(</span><span style="color: #b6a0e0;">id</span> <span style="color: #b58900;">&optional</span> <span style="color: #a6bb99;">parents</span> <span style="color: #e0d0a0;">options</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #b3c0a7;">list</span> <span style="color: #b6a0e0;">id</span> <span style="color: #a6bb99;">parents</span> <span style="color: #e0d0a0;">options</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/node-id</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #9999bb;">nth</span> <span style="color: #a7aac0;">0</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/node-parents</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #9999bb;">nth</span> <span style="color: #9999bb;">1</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/node-group</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #c0a7bd;">cdr</span> <span style="color: #268bd2;">(</span><span style="color: #bb99b4;">assoc</span> '<span style="color: #a7aac0;">group</span> <span style="color: #6c71c4;">(</span><span style="color: #9999bb;">nth</span> <span style="color: #a6bb99;">2</span> <span style="color: #99bbb4;">node</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/node-label</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #c0a7bd;">cdr</span> <span style="color: #268bd2;">(</span><span style="color: #bb99b4;">assoc</span> '<span style="color: #a7aac0;">label</span> <span style="color: #6c71c4;">(</span><span style="color: #9999bb;">nth</span> <span style="color: #a6bb99;">2</span> <span style="color: #99bbb4;">node</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-2-2" class="outline-3">
|
|
<h3 id="sec-2-2">Updating the Graphviz node generation</h3>
|
|
<div class="outline-text-3" id="text-2-2">
|
|
<p>
|
|
The next step was updating the Graphviz generation functions to handle
|
|
the new data structure, and set the shape and label attributes of
|
|
labeled nodes.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/to-graphviz-nodes"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-node</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">let</span> <span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #c0afa7;">node-id</span> <span style="color: #859900;">(</span><span style="color: #c0afa7;">git-graph/to-graphviz-node-id</span> <span style="color: #b58900;">(</span><span style="color: #e0d0a0;">git-graph/node-id</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #c0a7bd;">concat</span> <span style="color: #c0afa7;">node-id</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">git-graph/to-graphviz-node--attributes</span> <span style="color: #99bbb4;">node</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #2aa198;">";"</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-node--attributes</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">let</span> <span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">attributes</span> <span style="color: #859900;">(</span><span style="color: #99bbb4;">git-graph/to-graphviz-node--compute-attributes</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #b3c0a7;">and</span> <span style="color: #a3e0a0;">attributes</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #c0a7bd;">concat</span> <span style="color: #2aa198;">"["</span>
|
|
<span style="color: #859900;">(</span><span style="color: #b6a0e0;">mapconcat</span> <span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #268bd2;">(</span><span style="color: #a7aac0;">pair</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #a0d6e0;">format</span> <span style="color: #2aa198;">"%s=\"%s\""</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #99bbb4;">car</span> <span style="color: #a7aac0;">pair</span><span style="color: #6c71c4;">)</span> <span style="color: #6c71c4;">(</span><span style="color: #c0a7bd;">cdr</span> <span style="color: #a7aac0;">pair</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #a3e0a0;">attributes</span>
|
|
<span style="color: #2aa198;">", "</span><span style="color: #859900;">)</span>
|
|
<span style="color: #2aa198;">"]"</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-node--compute-attributes</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">-filter</span> #'<span style="color: #a3e0a0;">identity</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #a7aac0;">append</span> <span style="color: #6c71c4;">(</span><span style="color: #b3c0a7;">and</span> <span style="color: #859900;">(</span><span style="color: #b6a0e0;">git-graph/node-group</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #b3c0a7;">list</span> <span style="color: #b58900;">(</span><span style="color: #a0d6e0;">cons</span> '<span style="color: #a7aac0;">group</span> <span style="color: #268bd2;">(</span><span style="color: #b6a0e0;">git-graph/node-group</span> <span style="color: #99bbb4;">node</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #b3c0a7;">and</span> <span style="color: #859900;">(</span><span style="color: #e0a0bc;">git-graph/node-label</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #b3c0a7;">list</span> <span style="color: #b58900;">(</span><span style="color: #a0d6e0;">cons</span> '<span style="color: #a6bb99;">shape</span> '<span style="color: #bba699;">box</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a0d6e0;">cons</span> '<span style="color: #a7aac0;">label</span> <span style="color: #268bd2;">(</span><span style="color: #e0a0bc;">git-graph/node-label</span> <span style="color: #99bbb4;">node</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
I could then label the tips of each branch:
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="graph-example-labels"><span style="color: #2aa198;">(</span><span style="color: #b6a0e0;">git-graph/to-graphviz-pretty</span>
|
|
<span style="color: #2aa198;">"labeled"</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #b3c0a7;">list</span> <span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #9999bb;">1</span> <span style="color: #bb99b4;">nil</span> '<span style="color: #6c71c4;">(</span><span style="color: #859900;">(</span><span style="color: #a7aac0;">group</span> <span style="color: #b3c0a7;">.</span> <span style="color: #2aa198;">"master"</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a6bb99;">2</span> '<span style="color: #6c71c4;">(</span><span style="color: #9999bb;">1</span><span style="color: #6c71c4;">)</span> '<span style="color: #6c71c4;">(</span><span style="color: #859900;">(</span><span style="color: #a7aac0;">group</span> <span style="color: #b3c0a7;">.</span> <span style="color: #2aa198;">"master"</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #e0a0bc;">3</span> '<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">2</span><span style="color: #6c71c4;">)</span> '<span style="color: #6c71c4;">(</span><span style="color: #859900;">(</span><span style="color: #a7aac0;">group</span> <span style="color: #b3c0a7;">.</span> <span style="color: #2aa198;">"master"</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a0d6e0;">4</span> '<span style="color: #6c71c4;">(</span><span style="color: #e0a0bc;">3</span> <span style="color: #e0a0bc;">7</span><span style="color: #6c71c4;">)</span> '<span style="color: #6c71c4;">(</span><span style="color: #859900;">(</span><span style="color: #a7aac0;">group</span> <span style="color: #b3c0a7;">.</span> <span style="color: #2aa198;">"master"</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a3e0a0;">5</span> '<span style="color: #6c71c4;">(</span><span style="color: #a0d6e0;">4</span><span style="color: #6c71c4;">)</span> '<span style="color: #6c71c4;">(</span><span style="color: #859900;">(</span><span style="color: #a7aac0;">group</span> <span style="color: #b3c0a7;">.</span> <span style="color: #2aa198;">"master"</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #a7aac0;">label</span> <span style="color: #b3c0a7;">.</span> <span style="color: #2aa198;">"master"</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a3e0a0;">6</span> '<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">2</span><span style="color: #6c71c4;">)</span> '<span style="color: #6c71c4;">(</span><span style="color: #859900;">(</span><span style="color: #a7aac0;">group</span> <span style="color: #b3c0a7;">.</span> <span style="color: #2aa198;">"branch"</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #e0a0bc;">7</span> '<span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">6</span><span style="color: #6c71c4;">)</span> '<span style="color: #6c71c4;">(</span><span style="color: #859900;">(</span><span style="color: #a7aac0;">group</span> <span style="color: #b3c0a7;">.</span> <span style="color: #2aa198;">"branch"</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #a7aac0;">label</span> <span style="color: #b3c0a7;">.</span> <span style="color: #2aa198;">"branch"</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-dot">digraph <span style="color: #268bd2;">labeled</span> {
|
|
<span style="color: #268bd2;">bgcolor=</span><span style="color: #2aa198;">"transparent"</span>;
|
|
<span style="color: #268bd2;">rankdir=</span><span style="color: #2aa198;">"LR"</span>;
|
|
node[<span style="color: #268bd2;">width=</span>0.15,<span style="color: #268bd2;">height=</span>0.15,<span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">point</span>,<span style="color: #268bd2;">fontsize=</span>8.0];
|
|
edge[<span style="color: #268bd2;">weight=</span>2,<span style="color: #268bd2;">arrowhead=</span><span style="color: #268bd2; font-weight: bold;">none</span>];
|
|
<span style="color: #2aa198;">"1"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"2"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"3"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"4"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"5"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"master"</span>, <span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"6"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"branch"</span>];
|
|
<span style="color: #2aa198;">"7"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"branch"</span>, <span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"branch"</span>];
|
|
<span style="color: #2aa198;">"1"</span> -> <span style="color: #2aa198;">"2"</span>;
|
|
<span style="color: #2aa198;">"2"</span> -> <span style="color: #2aa198;">"3"</span>;
|
|
<span style="color: #2aa198;">"3"</span> -> <span style="color: #2aa198;">"4"</span>;
|
|
<span style="color: #2aa198;">"7"</span> -> <span style="color: #2aa198;">"4"</span>;
|
|
<span style="color: #2aa198;">"4"</span> -> <span style="color: #2aa198;">"5"</span>;
|
|
<span style="color: #2aa198;">"2"</span> -> <span style="color: #2aa198;">"6"</span>;
|
|
<span style="color: #2aa198;">"6"</span> -> <span style="color: #2aa198;">"7"</span>;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
-->
|
|
<!-- Title: labeled Pages: 1 -->
|
|
<svg width="307pt" height="58pt"
|
|
viewBox="0.00 0.00 307.20 58.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 54)">
|
|
<title>labeled</title>
|
|
<!-- 1 -->
|
|
<g id="node1" class="node"><title>1</title>
|
|
<ellipse fill="black" stroke="black" cx="5.4" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2 -->
|
|
<g id="node2" class="node"><title>2</title>
|
|
<ellipse fill="black" stroke="black" cx="52.2" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 1->2 -->
|
|
<g id="edge1" class="edge"><title>1->2</title>
|
|
<path fill="none" stroke="black" d="M10.8594,-41.5C19.4466,-41.5 38.1856,-41.5 46.7587,-41.5"/>
|
|
</g>
|
|
<!-- 3 -->
|
|
<g id="node3" class="node"><title>3</title>
|
|
<ellipse fill="black" stroke="black" cx="159.4" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->3 -->
|
|
<g id="edge2" class="edge"><title>2->3</title>
|
|
<path fill="none" stroke="black" d="M57.7203,-41.5C74.8673,-41.5 135.82,-41.5 153.537,-41.5"/>
|
|
</g>
|
|
<!-- 6 -->
|
|
<g id="node6" class="node"><title>6</title>
|
|
<ellipse fill="black" stroke="black" cx="99" cy="-8.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->6 -->
|
|
<g id="edge6" class="edge"><title>2->6</title>
|
|
<path fill="none" stroke="black" d="M57.0196,-38.6864C65.4836,-32.4518 85.7351,-17.5344 94.19,-11.3064"/>
|
|
</g>
|
|
<!-- 4 -->
|
|
<g id="node4" class="node"><title>4</title>
|
|
<ellipse fill="black" stroke="black" cx="219.8" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 3->4 -->
|
|
<g id="edge3" class="edge"><title>3->4</title>
|
|
<path fill="none" stroke="black" d="M164.983,-41.5C175.953,-41.5 203.614,-41.5 214.399,-41.5"/>
|
|
</g>
|
|
<!-- 5 -->
|
|
<g id="node5" class="node"><title>5</title>
|
|
<polygon fill="none" stroke="black" points="299.2,-50 261.2,-50 261.2,-33 299.2,-33 299.2,-50"/>
|
|
<text text-anchor="middle" x="280.2" y="-39.6" font-family="Times,serif" font-size="8.00">master</text>
|
|
</g>
|
|
<!-- 4->5 -->
|
|
<g id="edge5" class="edge"><title>4->5</title>
|
|
<path fill="none" stroke="black" d="M225.383,-41.5C232.965,-41.5 248.521,-41.5 260.967,-41.5"/>
|
|
</g>
|
|
<!-- 7 -->
|
|
<g id="node7" class="node"><title>7</title>
|
|
<polygon fill="none" stroke="black" points="178.4,-17 140.4,-17 140.4,-0 178.4,-0 178.4,-17"/>
|
|
<text text-anchor="middle" x="159.4" y="-6.6" font-family="Times,serif" font-size="8.00">branch</text>
|
|
</g>
|
|
<!-- 6->7 -->
|
|
<g id="edge7" class="edge"><title>6->7</title>
|
|
<path fill="none" stroke="black" d="M104.583,-8.5C112.165,-8.5 127.721,-8.5 140.167,-8.5"/>
|
|
</g>
|
|
<!-- 7->4 -->
|
|
<g id="edge4" class="edge"><title>7->4</title>
|
|
<path fill="none" stroke="black" d="M175.744,-17.1704C188.721,-24.5034 206.452,-34.5223 214.506,-39.0734"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-3" class="outline-2">
|
|
<h2 id="sec-3">Automatic Grouping Using Leaf Nodes</h2>
|
|
<div class="outline-text-2" id="text-3">
|
|
<p>
|
|
Manually assigning groups to each node is tedious, and easy to
|
|
accidentally get wrong. Also, with the goal to graph git repositories,
|
|
I was going to have to figure out groupings automatically anyway.
|
|
</p>
|
|
|
|
<p>
|
|
To do this, it made sense to traverse the nodes in <a href="https://en.wikipedia.org/wiki/Topological_sorting">topological order</a>.
|
|
</p>
|
|
|
|
<p>
|
|
Repeating the example above,
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-dot">digraph <span style="color: #268bd2;">G</span> {
|
|
<span style="color: #268bd2;">rankdir=</span><span style="color: #2aa198;">"LR"</span>;
|
|
<span style="color: #268bd2;">bgcolor=</span><span style="color: #2aa198;">"transparent"</span>;
|
|
node[<span style="color: #268bd2;">width=</span>0.15, <span style="color: #268bd2;">height=</span>0.15, <span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">circle</span>];
|
|
edge[<span style="color: #268bd2;">weight=</span>2, <span style="color: #268bd2;">arrowhead=</span><span style="color: #268bd2; font-weight: bold;">none</span>];
|
|
node[<span style="color: #268bd2;">group=</span>main];
|
|
1 -> 2 -> 3 -> 4 -> 5;
|
|
node[<span style="color: #268bd2;">group=</span>branch1];
|
|
2 -> 6 -> 7 -> 4;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
-->
|
|
<!-- Title: G Pages: 1 -->
|
|
<svg width="383pt" height="92pt"
|
|
viewBox="0.00 0.00 383.16 91.53" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 87.5269)">
|
|
<title>G</title>
|
|
<!-- 1 -->
|
|
<g id="node1" class="node"><title>1</title>
|
|
<ellipse fill="none" stroke="black" cx="16.2635" cy="-67.2635" rx="16.0303" ry="16.0303"/>
|
|
<text text-anchor="middle" x="16.2635" y="-63.5635" font-family="Times,serif" font-size="14.00">1</text>
|
|
</g>
|
|
<!-- 2 -->
|
|
<g id="node2" class="node"><title>2</title>
|
|
<ellipse fill="none" stroke="black" cx="84.7904" cy="-67.2635" rx="16.0303" ry="16.0303"/>
|
|
<text text-anchor="middle" x="84.7904" y="-63.5635" font-family="Times,serif" font-size="14.00">2</text>
|
|
</g>
|
|
<!-- 1->2 -->
|
|
<g id="edge1" class="edge"><title>1->2</title>
|
|
<path fill="none" stroke="black" d="M32.6933,-67.2635C43.4409,-67.2635 57.715,-67.2635 68.4442,-67.2635"/>
|
|
</g>
|
|
<!-- 3 -->
|
|
<g id="node3" class="node"><title>3</title>
|
|
<ellipse fill="none" stroke="black" cx="221.844" cy="-67.2635" rx="16.0303" ry="16.0303"/>
|
|
<text text-anchor="middle" x="221.844" y="-63.5635" font-family="Times,serif" font-size="14.00">3</text>
|
|
</g>
|
|
<!-- 2->3 -->
|
|
<g id="edge2" class="edge"><title>2->3</title>
|
|
<path fill="none" stroke="black" d="M101.283,-67.2635C127.334,-67.2635 179.603,-67.2635 205.532,-67.2635"/>
|
|
</g>
|
|
<!-- 6 -->
|
|
<g id="node6" class="node"><title>6</title>
|
|
<ellipse fill="none" stroke="black" cx="153.317" cy="-16.2635" rx="16.0303" ry="16.0303"/>
|
|
<text text-anchor="middle" x="153.317" y="-12.5635" font-family="Times,serif" font-size="14.00">6</text>
|
|
</g>
|
|
<!-- 2->6 -->
|
|
<g id="edge5" class="edge"><title>2->6</title>
|
|
<path fill="none" stroke="black" d="M98.3036,-57.6707C110.198,-48.5528 127.985,-34.9169 139.86,-25.8132"/>
|
|
</g>
|
|
<!-- 4 -->
|
|
<g id="node4" class="node"><title>4</title>
|
|
<ellipse fill="none" stroke="black" cx="290.371" cy="-67.2635" rx="16.0303" ry="16.0303"/>
|
|
<text text-anchor="middle" x="290.371" y="-63.5635" font-family="Times,serif" font-size="14.00">4</text>
|
|
</g>
|
|
<!-- 3->4 -->
|
|
<g id="edge3" class="edge"><title>3->4</title>
|
|
<path fill="none" stroke="black" d="M238.274,-67.2635C249.022,-67.2635 263.296,-67.2635 274.025,-67.2635"/>
|
|
</g>
|
|
<!-- 5 -->
|
|
<g id="node5" class="node"><title>5</title>
|
|
<ellipse fill="none" stroke="black" cx="358.898" cy="-67.2635" rx="16.0303" ry="16.0303"/>
|
|
<text text-anchor="middle" x="358.898" y="-63.5635" font-family="Times,serif" font-size="14.00">5</text>
|
|
</g>
|
|
<!-- 4->5 -->
|
|
<g id="edge4" class="edge"><title>4->5</title>
|
|
<path fill="none" stroke="black" d="M306.801,-67.2635C317.549,-67.2635 331.823,-67.2635 342.552,-67.2635"/>
|
|
</g>
|
|
<!-- 7 -->
|
|
<g id="node7" class="node"><title>7</title>
|
|
<ellipse fill="none" stroke="black" cx="221.844" cy="-16.2635" rx="16.0303" ry="16.0303"/>
|
|
<text text-anchor="middle" x="221.844" y="-12.5635" font-family="Times,serif" font-size="14.00">7</text>
|
|
</g>
|
|
<!-- 6->7 -->
|
|
<g id="edge6" class="edge"><title>6->7</title>
|
|
<path fill="none" stroke="black" d="M169.747,-16.2635C180.495,-16.2635 194.769,-16.2635 205.498,-16.2635"/>
|
|
</g>
|
|
<!-- 7->4 -->
|
|
<g id="edge7" class="edge"><title>7->4</title>
|
|
<path fill="none" stroke="black" d="M235.357,-25.8562C247.251,-34.9742 265.039,-48.61 276.914,-57.7138"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
|
|
<p>
|
|
These nodes can be represented (right to left) in topological order as
|
|
either <code>5, 4, 3, 7, 6, 2, 1</code> or <code>5, 4, 7, 6, 3, 2, 1</code>.
|
|
</p>
|
|
|
|
<p>
|
|
Having no further children, <code>5</code> is a leaf node, and can be used as a
|
|
group. All first parents of <code>5</code> can therefore be considered to be in
|
|
group <code>5</code>.
|
|
</p>
|
|
|
|
<p>
|
|
<code>7</code> is a second parent to <code>4</code>, and so should be used as the group for
|
|
all of its parents not present in group <code>5</code>.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/group-topo"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/group-topo</span> <span style="color: #b58900;">(</span><span style="color: #a7aac0;">nodelist</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #c0afa7;">reverse</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #99bbb4;">car</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #859900; font-weight: bold;">-reduce-from</span>
|
|
<span style="color: #859900;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #b58900;">(</span><span style="color: #268bd2;">acc</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">let*</span> <span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">grouped-nodes</span> <span style="color: #859900;">(</span><span style="color: #99bbb4;">car</span> <span style="color: #268bd2;">acc</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">group-stack</span> <span style="color: #859900;">(</span><span style="color: #c0a7bd;">cdr</span> <span style="color: #268bd2;">acc</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #c0afa7;">node-id</span> <span style="color: #859900;">(</span><span style="color: #e0d0a0;">git-graph/node-id</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a7c0b9;">group-from-stack</span> <span style="color: #859900;">(</span><span style="color: #859900; font-weight: bold;">--if-let</span> <span style="color: #2aa198;">(</span><span style="color: #bb99b4;">assoc</span> <span style="color: #c0afa7;">node-id</span> <span style="color: #a6bb99;">group-stack</span><span style="color: #2aa198;">)</span>
|
|
<span style="color: #2aa198;">(</span><span style="color: #c0a7bd;">cdr</span> <span style="color: #268bd2;">it</span><span style="color: #2aa198;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a7aac0;">group</span> <span style="color: #859900;">(</span><span style="color: #a7aac0;">or</span> <span style="color: #a7c0b9;">group-from-stack</span> <span style="color: #c0afa7;">node-id</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">parents</span> <span style="color: #859900;">(</span><span style="color: #a7c0b9;">git-graph/node-parents</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #b6a0e0;">first-parent</span> <span style="color: #859900;">(</span><span style="color: #a0d6e0;">first</span> <span style="color: #a6bb99;">parents</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">if</span> <span style="color: #a7c0b9;">group-from-stack</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #99bbb4;">pop</span> <span style="color: #a6bb99;">group-stack</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">if</span> <span style="color: #6c71c4;">(</span><span style="color: #b3c0a7;">and</span> <span style="color: #b6a0e0;">first-parent</span> <span style="color: #859900;">(</span><span style="color: #9999bb;">not</span> <span style="color: #2aa198;">(</span><span style="color: #bb99b4;">assoc</span> <span style="color: #b6a0e0;">first-parent</span> <span style="color: #a6bb99;">group-stack</span><span style="color: #2aa198;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">push</span> <span style="color: #859900;">(</span><span style="color: #a0d6e0;">cons</span> <span style="color: #b6a0e0;">first-parent</span> <span style="color: #a7aac0;">group</span><span style="color: #859900;">)</span> <span style="color: #a6bb99;">group-stack</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #a0d6e0;">cons</span> <span style="color: #6c71c4;">(</span><span style="color: #a0d6e0;">cons</span> <span style="color: #859900;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #c0afa7;">node-id</span>
|
|
<span style="color: #a6bb99;">parents</span>
|
|
`<span style="color: #2aa198;">(</span><span style="color: #b58900;">(</span><span style="color: #a7aac0;">group</span> <span style="color: #b3c0a7;">.</span> ,<span style="color: #a7aac0;">group</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a7aac0;">label</span> <span style="color: #b3c0a7;">.</span> ,<span style="color: #268bd2;">(</span><span style="color: #e0a0bc;">git-graph/node-label</span> <span style="color: #99bbb4;">node</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span><span style="color: #859900;">)</span>
|
|
<span style="color: #a3e0a0;">grouped-nodes</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #a6bb99;">group-stack</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span>
|
|
<span style="color: #bb99b4;">nil</span>
|
|
<span style="color: #a7aac0;">nodelist</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
While iterating through the node list, I maintained a stack of pairs
|
|
built from the first parent of the current node, and the current
|
|
group. To determine the group, the head of the stack is checked to see
|
|
if it contains a group for the current node id. If it does, that group
|
|
is used and it is popped off the stack, otherwise the current node id
|
|
is used.
|
|
</p>
|
|
|
|
<p>
|
|
The following table illustrates how the stack is used to store and
|
|
assign group relationships as the process iterates through the node
|
|
list:
|
|
</p>
|
|
|
|
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
|
|
<caption class="t-above"><span class="table-number">Table 1:</span> Progressing through the nodes</caption>
|
|
|
|
<colgroup>
|
|
<col class="right" />
|
|
|
|
<col class="left" />
|
|
|
|
<col class="left" />
|
|
|
|
<col class="right" />
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th scope="col" class="right">Node</th>
|
|
<th scope="col" class="left">Parents</th>
|
|
<th scope="col" class="left">Group Stack</th>
|
|
<th scope="col" class="right">Group</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="right">5</td>
|
|
<td class="left">(4)</td>
|
|
<td class="left">(4 . 5)</td>
|
|
<td class="right">5</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="right">4</td>
|
|
<td class="left">(3 7)</td>
|
|
<td class="left">(3 . 5)</td>
|
|
<td class="right">5</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="right">3</td>
|
|
<td class="left">(2)</td>
|
|
<td class="left">(2 . 5)</td>
|
|
<td class="right">5</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="right">7</td>
|
|
<td class="left">(6)</td>
|
|
<td class="left">(6 . 7) (2 . 5)</td>
|
|
<td class="right">7</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="right">6</td>
|
|
<td class="left">(2)</td>
|
|
<td class="left">(2 . 5)</td>
|
|
<td class="right">7</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="right">2</td>
|
|
<td class="left">(1)</td>
|
|
<td class="left">(1 . 5)</td>
|
|
<td class="right">5</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="right">1</td>
|
|
<td class="left"> </td>
|
|
<td class="left"> </td>
|
|
<td class="right">5</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
|
|
<div id="outline-container-sec-3-1" class="outline-3">
|
|
<h3 id="sec-3-1">Graph without automatic grouping</h3>
|
|
<div class="outline-text-3" id="text-3-1">
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="graph-no-auto-grouping"><span style="color: #2aa198;">(</span><span style="color: #b6a0e0;">git-graph/to-graphviz-pretty</span>
|
|
<span style="color: #2aa198;">"nogroups"</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #b3c0a7;">list</span> <span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a3e0a0;">5</span> '<span style="color: #6c71c4;">(</span><span style="color: #a0d6e0;">4</span><span style="color: #6c71c4;">)</span> '<span style="color: #6c71c4;">(</span><span style="color: #859900;">(</span><span style="color: #a7aac0;">label</span> <span style="color: #b3c0a7;">.</span> <span style="color: #c0a7bd;">master</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a0d6e0;">4</span> '<span style="color: #6c71c4;">(</span><span style="color: #e0a0bc;">3</span> <span style="color: #e0a0bc;">7</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #e0a0bc;">3</span> '<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">2</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #e0a0bc;">7</span> '<span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">6</span><span style="color: #6c71c4;">)</span> '<span style="color: #6c71c4;">(</span><span style="color: #859900;">(</span><span style="color: #a7aac0;">label</span> <span style="color: #b3c0a7;">.</span> <span style="color: #c0a7bd;">develop</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a3e0a0;">6</span> '<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">2</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a6bb99;">2</span> '<span style="color: #6c71c4;">(</span><span style="color: #9999bb;">1</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #9999bb;">1</span> <span style="color: #bb99b4;">nil</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-dot">digraph <span style="color: #268bd2;">nogroups</span> {
|
|
<span style="color: #268bd2;">bgcolor=</span><span style="color: #2aa198;">"transparent"</span>;
|
|
<span style="color: #268bd2;">rankdir=</span><span style="color: #2aa198;">"LR"</span>;
|
|
node[<span style="color: #268bd2;">width=</span>0.15,<span style="color: #268bd2;">height=</span>0.15,<span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">point</span>,<span style="color: #268bd2;">fontsize=</span>8.0];
|
|
edge[<span style="color: #268bd2;">weight=</span>2,<span style="color: #268bd2;">arrowhead=</span><span style="color: #268bd2; font-weight: bold;">none</span>];
|
|
<span style="color: #2aa198;">"5"</span>[<span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"4"</span>;
|
|
<span style="color: #2aa198;">"3"</span>;
|
|
<span style="color: #2aa198;">"7"</span>[<span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"develop"</span>];
|
|
<span style="color: #2aa198;">"6"</span>;
|
|
<span style="color: #2aa198;">"2"</span>;
|
|
<span style="color: #2aa198;">"1"</span>;
|
|
<span style="color: #2aa198;">"4"</span> -> <span style="color: #2aa198;">"5"</span>;
|
|
<span style="color: #2aa198;">"3"</span> -> <span style="color: #2aa198;">"4"</span>;
|
|
<span style="color: #2aa198;">"7"</span> -> <span style="color: #2aa198;">"4"</span>;
|
|
<span style="color: #2aa198;">"2"</span> -> <span style="color: #2aa198;">"3"</span>;
|
|
<span style="color: #2aa198;">"6"</span> -> <span style="color: #2aa198;">"7"</span>;
|
|
<span style="color: #2aa198;">"2"</span> -> <span style="color: #2aa198;">"6"</span>;
|
|
<span style="color: #2aa198;">"1"</span> -> <span style="color: #2aa198;">"2"</span>;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
-->
|
|
<!-- Title: nogroups Pages: 1 -->
|
|
<svg width="310pt" height="54pt"
|
|
viewBox="0.00 0.00 310.20 53.90" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 49.9)">
|
|
<title>nogroups</title>
|
|
<!-- 5 -->
|
|
<g id="node1" class="node"><title>5</title>
|
|
<polygon fill="none" stroke="black" points="302.2,-33 264.2,-33 264.2,-16 302.2,-16 302.2,-33"/>
|
|
<text text-anchor="middle" x="283.2" y="-22.6" font-family="Times,serif" font-size="8.00">master</text>
|
|
</g>
|
|
<!-- 4 -->
|
|
<g id="node2" class="node"><title>4</title>
|
|
<ellipse fill="black" stroke="black" cx="222.8" cy="-24.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 4->5 -->
|
|
<g id="edge1" class="edge"><title>4->5</title>
|
|
<path fill="none" stroke="black" d="M228.383,-24.5C235.965,-24.5 251.521,-24.5 263.967,-24.5"/>
|
|
</g>
|
|
<!-- 3 -->
|
|
<g id="node3" class="node"><title>3</title>
|
|
<ellipse fill="black" stroke="black" cx="160.9" cy="-40.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 3->4 -->
|
|
<g id="edge2" class="edge"><title>3->4</title>
|
|
<path fill="none" stroke="black" d="M166.208,-39.3493C177.153,-36.4259 205.956,-28.7322 217.205,-25.7273"/>
|
|
</g>
|
|
<!-- 7 -->
|
|
<g id="node4" class="node"><title>7</title>
|
|
<polygon fill="none" stroke="black" points="181.4,-17 140.4,-17 140.4,-0 181.4,-0 181.4,-17"/>
|
|
<text text-anchor="middle" x="160.9" y="-6.6" font-family="Times,serif" font-size="8.00">develop</text>
|
|
</g>
|
|
<!-- 7->4 -->
|
|
<g id="edge3" class="edge"><title>7->4</title>
|
|
<path fill="none" stroke="black" d="M181.514,-13.739C194.343,-17.1658 210.056,-21.363 217.498,-23.3509"/>
|
|
</g>
|
|
<!-- 6 -->
|
|
<g id="node5" class="node"><title>6</title>
|
|
<ellipse fill="black" stroke="black" cx="99" cy="-8.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 6->7 -->
|
|
<g id="edge5" class="edge"><title>6->7</title>
|
|
<path fill="none" stroke="black" d="M104.7,-8.5C112.312,-8.5 127.758,-8.5 140.38,-8.5"/>
|
|
</g>
|
|
<!-- 2 -->
|
|
<g id="node6" class="node"><title>2</title>
|
|
<ellipse fill="black" stroke="black" cx="52.2" cy="-24.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->3 -->
|
|
<g id="edge4" class="edge"><title>2->3</title>
|
|
<path fill="none" stroke="black" d="M57.7848,-25.1875C75.3358,-27.8193 138.136,-37.2364 155.451,-39.8329"/>
|
|
</g>
|
|
<!-- 2->6 -->
|
|
<g id="edge6" class="edge"><title>2->6</title>
|
|
<path fill="none" stroke="black" d="M57.6594,-22.9074C66.2466,-19.8405 84.9856,-13.148 93.5587,-10.0862"/>
|
|
</g>
|
|
<!-- 1 -->
|
|
<g id="node7" class="node"><title>1</title>
|
|
<ellipse fill="black" stroke="black" cx="5.4" cy="-24.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 1->2 -->
|
|
<g id="edge7" class="edge"><title>1->2</title>
|
|
<path fill="none" stroke="black" d="M10.8594,-24.5C19.4466,-24.5 38.1856,-24.5 46.7587,-24.5"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-3-2" class="outline-3">
|
|
<h3 id="sec-3-2">Graph with automatic grouping</h3>
|
|
<div class="outline-text-3" id="text-3-2">
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="graph-with-auto-grouping"><span style="color: #2aa198;">(</span><span style="color: #b6a0e0;">git-graph/to-graphviz-pretty</span>
|
|
<span style="color: #2aa198;">"autogroups"</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #b3c0a7;">git-graph/group-topo</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #b3c0a7;">list</span> <span style="color: #6c71c4;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a3e0a0;">5</span> '<span style="color: #859900;">(</span><span style="color: #a0d6e0;">4</span><span style="color: #859900;">)</span> '<span style="color: #859900;">(</span><span style="color: #b58900;">(</span><span style="color: #a7aac0;">label</span> <span style="color: #b3c0a7;">.</span> <span style="color: #c0a7bd;">master</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a0d6e0;">4</span> '<span style="color: #859900;">(</span><span style="color: #e0a0bc;">3</span> <span style="color: #e0a0bc;">7</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #e0a0bc;">3</span> '<span style="color: #859900;">(</span><span style="color: #a6bb99;">2</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #e0a0bc;">7</span> '<span style="color: #859900;">(</span><span style="color: #a3e0a0;">6</span><span style="color: #859900;">)</span> '<span style="color: #859900;">(</span><span style="color: #b58900;">(</span><span style="color: #a7aac0;">label</span> <span style="color: #b3c0a7;">.</span> <span style="color: #c0a7bd;">develop</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a3e0a0;">6</span> '<span style="color: #859900;">(</span><span style="color: #a6bb99;">2</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a6bb99;">2</span> '<span style="color: #859900;">(</span><span style="color: #9999bb;">1</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #9999bb;">1</span> <span style="color: #bb99b4;">nil</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-dot">digraph <span style="color: #268bd2;">autogroups</span> {
|
|
<span style="color: #268bd2;">bgcolor=</span><span style="color: #2aa198;">"transparent"</span>;
|
|
<span style="color: #268bd2;">rankdir=</span><span style="color: #2aa198;">"LR"</span>;
|
|
node[<span style="color: #268bd2;">width=</span>0.15,<span style="color: #268bd2;">height=</span>0.15,<span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">point</span>,<span style="color: #268bd2;">fontsize=</span>8.0];
|
|
edge[<span style="color: #268bd2;">weight=</span>2,<span style="color: #268bd2;">arrowhead=</span><span style="color: #268bd2; font-weight: bold;">none</span>];
|
|
<span style="color: #2aa198;">"5"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"5"</span>, <span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"4"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"5"</span>];
|
|
<span style="color: #2aa198;">"3"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"5"</span>];
|
|
<span style="color: #2aa198;">"7"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"7"</span>, <span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"develop"</span>];
|
|
<span style="color: #2aa198;">"6"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"7"</span>];
|
|
<span style="color: #2aa198;">"2"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"5"</span>];
|
|
<span style="color: #2aa198;">"1"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"5"</span>];
|
|
<span style="color: #2aa198;">"4"</span> -> <span style="color: #2aa198;">"5"</span>;
|
|
<span style="color: #2aa198;">"3"</span> -> <span style="color: #2aa198;">"4"</span>;
|
|
<span style="color: #2aa198;">"7"</span> -> <span style="color: #2aa198;">"4"</span>;
|
|
<span style="color: #2aa198;">"2"</span> -> <span style="color: #2aa198;">"3"</span>;
|
|
<span style="color: #2aa198;">"6"</span> -> <span style="color: #2aa198;">"7"</span>;
|
|
<span style="color: #2aa198;">"2"</span> -> <span style="color: #2aa198;">"6"</span>;
|
|
<span style="color: #2aa198;">"1"</span> -> <span style="color: #2aa198;">"2"</span>;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
-->
|
|
<!-- Title: autogroups Pages: 1 -->
|
|
<svg width="310pt" height="58pt"
|
|
viewBox="0.00 0.00 310.20 58.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 54)">
|
|
<title>autogroups</title>
|
|
<!-- 5 -->
|
|
<g id="node1" class="node"><title>5</title>
|
|
<polygon fill="none" stroke="black" points="302.2,-50 264.2,-50 264.2,-33 302.2,-33 302.2,-50"/>
|
|
<text text-anchor="middle" x="283.2" y="-39.6" font-family="Times,serif" font-size="8.00">master</text>
|
|
</g>
|
|
<!-- 4 -->
|
|
<g id="node2" class="node"><title>4</title>
|
|
<ellipse fill="black" stroke="black" cx="222.8" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 4->5 -->
|
|
<g id="edge1" class="edge"><title>4->5</title>
|
|
<path fill="none" stroke="black" d="M228.383,-41.5C235.965,-41.5 251.521,-41.5 263.967,-41.5"/>
|
|
</g>
|
|
<!-- 3 -->
|
|
<g id="node3" class="node"><title>3</title>
|
|
<ellipse fill="black" stroke="black" cx="160.9" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 3->4 -->
|
|
<g id="edge2" class="edge"><title>3->4</title>
|
|
<path fill="none" stroke="black" d="M166.6,-41.5C177.853,-41.5 206.224,-41.5 217.285,-41.5"/>
|
|
</g>
|
|
<!-- 7 -->
|
|
<g id="node4" class="node"><title>7</title>
|
|
<polygon fill="none" stroke="black" points="181.4,-17 140.4,-17 140.4,-0 181.4,-0 181.4,-17"/>
|
|
<text text-anchor="middle" x="160.9" y="-6.6" font-family="Times,serif" font-size="8.00">develop</text>
|
|
</g>
|
|
<!-- 7->4 -->
|
|
<g id="edge3" class="edge"><title>7->4</title>
|
|
<path fill="none" stroke="black" d="M177.638,-17.1704C190.949,-24.5034 209.134,-34.5223 217.395,-39.0734"/>
|
|
</g>
|
|
<!-- 6 -->
|
|
<g id="node5" class="node"><title>6</title>
|
|
<ellipse fill="black" stroke="black" cx="99" cy="-8.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 6->7 -->
|
|
<g id="edge5" class="edge"><title>6->7</title>
|
|
<path fill="none" stroke="black" d="M104.7,-8.5C112.312,-8.5 127.758,-8.5 140.38,-8.5"/>
|
|
</g>
|
|
<!-- 2 -->
|
|
<g id="node6" class="node"><title>2</title>
|
|
<ellipse fill="black" stroke="black" cx="52.2" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->3 -->
|
|
<g id="edge4" class="edge"><title>2->3</title>
|
|
<path fill="none" stroke="black" d="M57.7848,-41.5C75.3358,-41.5 138.136,-41.5 155.451,-41.5"/>
|
|
</g>
|
|
<!-- 2->6 -->
|
|
<g id="edge6" class="edge"><title>2->6</title>
|
|
<path fill="none" stroke="black" d="M57.0196,-38.6864C65.4836,-32.4518 85.7351,-17.5344 94.19,-11.3064"/>
|
|
</g>
|
|
<!-- 1 -->
|
|
<g id="node7" class="node"><title>1</title>
|
|
<ellipse fill="black" stroke="black" cx="5.4" cy="-41.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 1->2 -->
|
|
<g id="edge7" class="edge"><title>1->2</title>
|
|
<path fill="none" stroke="black" d="M10.8594,-41.5C19.4466,-41.5 38.1856,-41.5 46.7587,-41.5"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-4" class="outline-2">
|
|
<h2 id="sec-4">Graphing a Git Repository</h2>
|
|
<div class="outline-text-2" id="text-4">
|
|
<p>
|
|
Satisfied that I had all the necessary tools to start graphing real
|
|
git repositories, I created an example repository to test against.
|
|
</p>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-4-1" class="outline-3">
|
|
<h3 id="sec-4-1">Creating a Sample Repository</h3>
|
|
<div class="outline-text-3" id="text-4-1">
|
|
<p>
|
|
Using the following script, I created a sample repository to test
|
|
against. I performed the following actions:
|
|
</p>
|
|
|
|
<ul class="org-ul">
|
|
<li>Forked a develop branch from master.
|
|
</li>
|
|
<li>Forked a feature branch from develop, with two commits.
|
|
</li>
|
|
<li>Added another commit to develop.
|
|
</li>
|
|
<li>Forked a second feature branch from develop, with two commits.
|
|
</li>
|
|
<li>Merged the second feature branch to develop.
|
|
</li>
|
|
<li>Merged develop to master and tagged it.
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-sh">mkdir /tmp/test.git
|
|
<span style="color: #839496; font-weight: bold;">cd</span> /tmp/test.git
|
|
git init
|
|
touch README
|
|
git add README
|
|
git commit -m <span style="color: #2aa198;">'initial'</span>
|
|
git commit --allow-empty -m <span style="color: #2aa198;">'first'</span>
|
|
git checkout -b develop
|
|
git commit --allow-empty -m <span style="color: #2aa198;">'second'</span>
|
|
git checkout -b feature-1
|
|
git commit --allow-empty -m <span style="color: #2aa198;">'feature 1'</span>
|
|
git commit --allow-empty -m <span style="color: #2aa198;">'feature 1 again'</span>
|
|
git checkout develop
|
|
git commit --allow-empty -m <span style="color: #2aa198;">'third'</span>
|
|
git checkout -b feature-2
|
|
git commit --allow-empty -m <span style="color: #2aa198;">'feature 2'</span>
|
|
git commit --allow-empty -m <span style="color: #2aa198;">'feature 2 again'</span>
|
|
git checkout develop
|
|
git merge --no-ff feature-2
|
|
git checkout master
|
|
git merge --no-ff develop
|
|
git tag -a 1.0
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="outline-container-sec-4-2" class="outline-3">
|
|
<h3 id="sec-4-2">Generating a Graph From a Git Branch</h3>
|
|
<div class="outline-text-3" id="text-4-2">
|
|
<p>
|
|
The first order of business was to have a way to call out to git and
|
|
return the results:
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/from-git"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/git-execute</span> <span style="color: #b58900;">(</span><span style="color: #9999bb;">repo-url</span> <span style="color: #b6a0e0;">command</span> <span style="color: #b58900;">&rest</span> <span style="color: #a6bb99;">args</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">with-temp-buffer</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #bba699;">shell-command</span> <span style="color: #6c71c4;">(</span><span style="color: #a0d6e0;">format</span> <span style="color: #2aa198;">"git -C \"%s\" %s"</span>
|
|
<span style="color: #9999bb;">repo-url</span>
|
|
<span style="color: #859900;">(</span><span style="color: #a7c0b9;">string-join</span> <span style="color: #b58900;">(</span><span style="color: #a0d6e0;">cons</span> <span style="color: #b6a0e0;">command</span> <span style="color: #a6bb99;">args</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #2aa198;">" "</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #a0d6e0;">t</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">buffer-string</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Next, I needed to get the list of commits for a branch in topological
|
|
order, with a list of parent commits for each. It turns out git
|
|
provides exactly that via its <code>rev-list</code> command.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/from-git"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/git-rev-list</span> <span style="color: #b58900;">(</span><span style="color: #9999bb;">repo-url</span> <span style="color: #a6bb99;">head</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">-map</span> <span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">line</span><span style="color: #6c71c4;">)</span> <span style="color: #6c71c4;">(</span><span style="color: #9999bb;">split-string</span> <span style="color: #a3e0a0;">line</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">split-string</span> <span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">git-graph/git-execute</span>
|
|
<span style="color: #9999bb;">repo-url</span>
|
|
<span style="color: #2aa198;">"rev-list"</span> <span style="color: #2aa198;">"--topo-order"</span> <span style="color: #2aa198;">"--parents"</span> <span style="color: #a6bb99;">head</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #2aa198;">"\n"</span> <span style="color: #a0d6e0;">t</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
I also wanted to label branch heads wherever possible. To do this, I
|
|
looked up the revision name from git, discarding it if it was relative
|
|
to some other named commit.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/from-git"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/git-label</span> <span style="color: #b58900;">(</span><span style="color: #9999bb;">repo-url</span> <span style="color: #a3e0a0;">rev</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">let</span> <span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #bba699;">name</span> <span style="color: #859900;">(</span><span style="color: #bba699;">string-trim</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a3e0a0;">git-graph/git-execute</span> <span style="color: #9999bb;">repo-url</span>
|
|
<span style="color: #2aa198;">"name-rev"</span> <span style="color: #2aa198;">"--name-only"</span> <span style="color: #a3e0a0;">rev</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">unless</span> <span style="color: #6c71c4;">(</span><span style="color: #c0a7bd;">s-contains?</span> <span style="color: #2aa198;">"~"</span> <span style="color: #bba699;">name</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #bba699;">name</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Generating the graph for a single branch was as simple as iterating
|
|
over each commit and creating a node for it.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/git-graph-head</span> <span style="color: #b58900;">(</span><span style="color: #9999bb;">repo-url</span> <span style="color: #a6bb99;">head</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #b3c0a7;">git-graph/group-topo</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">-map</span> <span style="color: #6c71c4;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #859900;">(</span><span style="color: #e0d0a0;">rev-with-parents</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #859900; font-weight: bold;">let*</span> <span style="color: #b58900;">(</span><span style="color: #268bd2;">(</span><span style="color: #a3e0a0;">rev</span> <span style="color: #6c71c4;">(</span><span style="color: #99bbb4;">car</span> <span style="color: #e0d0a0;">rev-with-parents</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #a6bb99;">parents</span> <span style="color: #6c71c4;">(</span><span style="color: #c0a7bd;">cdr</span> <span style="color: #e0d0a0;">rev-with-parents</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #a7aac0;">label</span> <span style="color: #6c71c4;">(</span><span style="color: #c0afa7;">git-graph/git-label</span> <span style="color: #9999bb;">repo-url</span> <span style="color: #a3e0a0;">rev</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #a3e0a0;">rev</span> <span style="color: #a6bb99;">parents</span>
|
|
`<span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #a7aac0;">label</span> <span style="color: #b3c0a7;">.</span> ,<span style="color: #a7aac0;">label</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #e0a0bc;">git-graph/git-rev-list</span> <span style="color: #9999bb;">repo-url</span> <span style="color: #a6bb99;">head</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Here's the result of graphing the <code>master</code> branch:
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="graph-git-branch"><span style="color: #2aa198;">(</span><span style="color: #b6a0e0;">git-graph/to-graphviz-pretty</span>
|
|
<span style="color: #2aa198;">"git"</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a7aac0;">git-graph/git-graph-head</span>
|
|
<span style="color: #2aa198;">"/tmp/test.git"</span>
|
|
<span style="color: #2aa198;">"master"</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-dot">digraph <span style="color: #268bd2;">git</span> {
|
|
<span style="color: #268bd2;">bgcolor=</span><span style="color: #2aa198;">"transparent"</span>;
|
|
<span style="color: #268bd2;">rankdir=</span><span style="color: #2aa198;">"LR"</span>;
|
|
node[<span style="color: #268bd2;">width=</span>0.15,<span style="color: #268bd2;">height=</span>0.15,<span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">point</span>,<span style="color: #268bd2;">fontsize=</span>8.0];
|
|
edge[<span style="color: #268bd2;">weight=</span>2,<span style="color: #268bd2;">arrowhead=</span><span style="color: #268bd2; font-weight: bold;">none</span>];
|
|
<span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>, <span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>, <span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"develop"</span>];
|
|
<span style="color: #2aa198;">"ee5c898281c0ba1965a2623e89bdfc1c6a767d4b"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"ee5c898281c0ba1965a2623e89bdfc1c6a767d4b"</span>, <span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"feature-2"</span>];
|
|
<span style="color: #2aa198;">"ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"ee5c898281c0ba1965a2623e89bdfc1c6a767d4b"</span>];
|
|
<span style="color: #2aa198;">"3992cf3e490b423591805d4c6bc335a34753f9d7"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>];
|
|
<span style="color: #2aa198;">"43c20e67d20b154ae0fbfd54ad946dd188732e83"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>];
|
|
<span style="color: #2aa198;">"cb495d05531ffb36b47f07bfde7b29547b60d68a"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>];
|
|
<span style="color: #2aa198;">"fe2eaeeb6a0f555c12e1304fa4738d2ce465a478"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>];
|
|
<span style="color: #2aa198;">"cb495d05531ffb36b47f07bfde7b29547b60d68a"</span> -> <span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>;
|
|
<span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span> -> <span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>;
|
|
<span style="color: #2aa198;">"3992cf3e490b423591805d4c6bc335a34753f9d7"</span> -> <span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>;
|
|
<span style="color: #2aa198;">"ee5c898281c0ba1965a2623e89bdfc1c6a767d4b"</span> -> <span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>;
|
|
<span style="color: #2aa198;">"ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b"</span> -> <span style="color: #2aa198;">"ee5c898281c0ba1965a2623e89bdfc1c6a767d4b"</span>;
|
|
<span style="color: #2aa198;">"3992cf3e490b423591805d4c6bc335a34753f9d7"</span> -> <span style="color: #2aa198;">"ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b"</span>;
|
|
<span style="color: #2aa198;">"43c20e67d20b154ae0fbfd54ad946dd188732e83"</span> -> <span style="color: #2aa198;">"3992cf3e490b423591805d4c6bc335a34753f9d7"</span>;
|
|
<span style="color: #2aa198;">"cb495d05531ffb36b47f07bfde7b29547b60d68a"</span> -> <span style="color: #2aa198;">"43c20e67d20b154ae0fbfd54ad946dd188732e83"</span>;
|
|
<span style="color: #2aa198;">"fe2eaeeb6a0f555c12e1304fa4738d2ce465a478"</span> -> <span style="color: #2aa198;">"cb495d05531ffb36b47f07bfde7b29547b60d68a"</span>;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
-->
|
|
<!-- Title: git Pages: 1 -->
|
|
<svg width="440pt" height="100pt"
|
|
viewBox="0.00 0.00 440.00 100.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 96)">
|
|
<title>git</title>
|
|
<!-- cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4 -->
|
|
<g id="node1" class="node"><title>cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4</title>
|
|
<polygon fill="none" stroke="black" points="432,-92 394,-92 394,-75 432,-75 432,-92"/>
|
|
<text text-anchor="middle" x="413" y="-81.6" font-family="Times,serif" font-size="8.00">master</text>
|
|
</g>
|
|
<!-- 82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5 -->
|
|
<g id="node2" class="node"><title>82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5</title>
|
|
<polygon fill="none" stroke="black" points="358,-54 317,-54 317,-37 358,-37 358,-54"/>
|
|
<text text-anchor="middle" x="337.5" y="-43.6" font-family="Times,serif" font-size="8.00">develop</text>
|
|
</g>
|
|
<!-- 82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5->cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4 -->
|
|
<g id="edge2" class="edge"><title>82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5->cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4</title>
|
|
<path fill="none" stroke="black" d="M355.178,-54.1228C367.207,-60.3417 383.374,-68.7003 395.388,-74.9113"/>
|
|
</g>
|
|
<!-- ee5c898281c0ba1965a2623e89bdfc1c6a767d4b -->
|
|
<g id="node3" class="node"><title>ee5c898281c0ba1965a2623e89bdfc1c6a767d4b</title>
|
|
<polygon fill="none" stroke="black" points="281,-17 234,-17 234,-0 281,-0 281,-17"/>
|
|
<text text-anchor="middle" x="257.5" y="-6.6" font-family="Times,serif" font-size="8.00">feature-2</text>
|
|
</g>
|
|
<!-- ee5c898281c0ba1965a2623e89bdfc1c6a767d4b->82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5 -->
|
|
<g id="edge4" class="edge"><title>ee5c898281c0ba1965a2623e89bdfc1c6a767d4b->82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5</title>
|
|
<path fill="none" stroke="black" d="M276.591,-17.0815C289.192,-23.059 305.928,-30.9978 318.507,-36.965"/>
|
|
</g>
|
|
<!-- ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b -->
|
|
<g id="node4" class="node"><title>ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b</title>
|
|
<ellipse fill="black" stroke="black" cx="192.6" cy="-8.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b->ee5c898281c0ba1965a2623e89bdfc1c6a767d4b -->
|
|
<g id="edge5" class="edge"><title>ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b->ee5c898281c0ba1965a2623e89bdfc1c6a767d4b</title>
|
|
<path fill="none" stroke="black" d="M198.124,-8.5C205.56,-8.5 220.848,-8.5 233.914,-8.5"/>
|
|
</g>
|
|
<!-- 3992cf3e490b423591805d4c6bc335a34753f9d7 -->
|
|
<g id="node5" class="node"><title>3992cf3e490b423591805d4c6bc335a34753f9d7</title>
|
|
<ellipse fill="black" stroke="black" cx="145.8" cy="-45.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 3992cf3e490b423591805d4c6bc335a34753f9d7->82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5 -->
|
|
<g id="edge3" class="edge"><title>3992cf3e490b423591805d4c6bc335a34753f9d7->82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5</title>
|
|
<path fill="none" stroke="black" d="M151.489,-45.5C174.254,-45.5 273.896,-45.5 316.769,-45.5"/>
|
|
</g>
|
|
<!-- 3992cf3e490b423591805d4c6bc335a34753f9d7->ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b -->
|
|
<g id="edge6" class="edge"><title>3992cf3e490b423591805d4c6bc335a34753f9d7->ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b</title>
|
|
<path fill="none" stroke="black" d="M150.62,-42.3454C159.084,-35.3551 179.335,-18.6295 187.79,-11.6466"/>
|
|
</g>
|
|
<!-- 43c20e67d20b154ae0fbfd54ad946dd188732e83 -->
|
|
<g id="node6" class="node"><title>43c20e67d20b154ae0fbfd54ad946dd188732e83</title>
|
|
<ellipse fill="black" stroke="black" cx="99" cy="-45.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 43c20e67d20b154ae0fbfd54ad946dd188732e83->3992cf3e490b423591805d4c6bc335a34753f9d7 -->
|
|
<g id="edge7" class="edge"><title>43c20e67d20b154ae0fbfd54ad946dd188732e83->3992cf3e490b423591805d4c6bc335a34753f9d7</title>
|
|
<path fill="none" stroke="black" d="M104.459,-45.5C113.047,-45.5 131.786,-45.5 140.359,-45.5"/>
|
|
</g>
|
|
<!-- cb495d05531ffb36b47f07bfde7b29547b60d68a -->
|
|
<g id="node7" class="node"><title>cb495d05531ffb36b47f07bfde7b29547b60d68a</title>
|
|
<ellipse fill="black" stroke="black" cx="52.2" cy="-83.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- cb495d05531ffb36b47f07bfde7b29547b60d68a->cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4 -->
|
|
<g id="edge1" class="edge"><title>cb495d05531ffb36b47f07bfde7b29547b60d68a->cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4</title>
|
|
<path fill="none" stroke="black" d="M57.775,-83.5C71.1596,-83.5 111.404,-83.5 144.8,-83.5 144.8,-83.5 144.8,-83.5 258.5,-83.5 307.268,-83.5 364.752,-83.5 393.57,-83.5"/>
|
|
</g>
|
|
<!-- cb495d05531ffb36b47f07bfde7b29547b60d68a->43c20e67d20b154ae0fbfd54ad946dd188732e83 -->
|
|
<g id="edge8" class="edge"><title>cb495d05531ffb36b47f07bfde7b29547b60d68a->43c20e67d20b154ae0fbfd54ad946dd188732e83</title>
|
|
<path fill="none" stroke="black" d="M56.7154,-80.5182C65.0488,-73.4497 85.9357,-55.7331 94.3765,-48.5735"/>
|
|
</g>
|
|
<!-- fe2eaeeb6a0f555c12e1304fa4738d2ce465a478 -->
|
|
<g id="node8" class="node"><title>fe2eaeeb6a0f555c12e1304fa4738d2ce465a478</title>
|
|
<ellipse fill="black" stroke="black" cx="5.4" cy="-83.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- fe2eaeeb6a0f555c12e1304fa4738d2ce465a478->cb495d05531ffb36b47f07bfde7b29547b60d68a -->
|
|
<g id="edge9" class="edge"><title>fe2eaeeb6a0f555c12e1304fa4738d2ce465a478->cb495d05531ffb36b47f07bfde7b29547b60d68a</title>
|
|
<path fill="none" stroke="black" d="M10.8594,-83.5C19.4466,-83.5 38.1856,-83.5 46.7587,-83.5"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<div id="outline-container-sec-4-3" class="outline-3">
|
|
<h3 id="sec-4-3">Graphing Multiple Branches</h3>
|
|
<div class="outline-text-3" id="text-4-3">
|
|
<p>
|
|
To graph multiple branches, I needed a function for combining
|
|
histories. To do so, I simply append any nodes I don't already know
|
|
about in the first history from the second.
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/adder"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/+</span> <span style="color: #b58900;">(</span><span style="color: #9999bb;">a</span> <span style="color: #9999bb;">b</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a7aac0;">append</span> <span style="color: #9999bb;">a</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">-remove</span> <span style="color: #6c71c4;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #859900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #bb99b4;">assoc</span> <span style="color: #b58900;">(</span><span style="color: #e0d0a0;">git-graph/node-id</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span> <span style="color: #9999bb;">a</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #9999bb;">b</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
From there, all that remained was to accumulate the branch histories
|
|
and output the complete graph:
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="git-graph/from-git"><span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/git-load</span> <span style="color: #b58900;">(</span><span style="color: #9999bb;">repo-url</span> <span style="color: #a7c0b9;">heads</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">-reduce</span> #'<span style="color: #c0afa7;">git-graph/+</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">-map</span> <span style="color: #6c71c4;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #859900;">(</span><span style="color: #a6bb99;">head</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #a7aac0;">git-graph/git-graph-head</span> <span style="color: #9999bb;">repo-url</span> <span style="color: #a6bb99;">head</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #a7c0b9;">heads</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
And here's the example repository, graphed in full:
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp" id="graph-git-repo"><span style="color: #2aa198;">(</span><span style="color: #b6a0e0;">git-graph/to-graphviz-pretty</span>
|
|
<span style="color: #2aa198;">"git"</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #bb99b4;">git-graph/git-load</span>
|
|
<span style="color: #2aa198;">"/tmp/test.git"</span>
|
|
'<span style="color: #268bd2;">(</span><span style="color: #2aa198;">"master"</span> <span style="color: #2aa198;">"feature-1"</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-dot">digraph <span style="color: #268bd2;">git</span> {
|
|
<span style="color: #268bd2;">bgcolor=</span><span style="color: #2aa198;">"transparent"</span>;
|
|
<span style="color: #268bd2;">rankdir=</span><span style="color: #2aa198;">"LR"</span>;
|
|
node[<span style="color: #268bd2;">width=</span>0.15,<span style="color: #268bd2;">height=</span>0.15,<span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">point</span>,<span style="color: #268bd2;">fontsize=</span>8.0];
|
|
edge[<span style="color: #268bd2;">weight=</span>2,<span style="color: #268bd2;">arrowhead=</span><span style="color: #268bd2; font-weight: bold;">none</span>];
|
|
<span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>, <span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"master"</span>];
|
|
<span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>, <span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"develop"</span>];
|
|
<span style="color: #2aa198;">"ee5c898281c0ba1965a2623e89bdfc1c6a767d4b"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"ee5c898281c0ba1965a2623e89bdfc1c6a767d4b"</span>, <span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"feature-2"</span>];
|
|
<span style="color: #2aa198;">"ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"ee5c898281c0ba1965a2623e89bdfc1c6a767d4b"</span>];
|
|
<span style="color: #2aa198;">"3992cf3e490b423591805d4c6bc335a34753f9d7"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>];
|
|
<span style="color: #2aa198;">"43c20e67d20b154ae0fbfd54ad946dd188732e83"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>];
|
|
<span style="color: #2aa198;">"cb495d05531ffb36b47f07bfde7b29547b60d68a"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>];
|
|
<span style="color: #2aa198;">"fe2eaeeb6a0f555c12e1304fa4738d2ce465a478"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>];
|
|
<span style="color: #2aa198;">"6b3ccf19c49a57363607bc4ac9a3213f8f900f04"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"6b3ccf19c49a57363607bc4ac9a3213f8f900f04"</span>, <span style="color: #268bd2;">shape=</span><span style="color: #2aa198;">"box"</span>, <span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"feature-1"</span>];
|
|
<span style="color: #2aa198;">"5e0a1de946c0cefa35b007996d9a649e44adec5e"</span>[<span style="color: #268bd2;">group=</span><span style="color: #2aa198;">"6b3ccf19c49a57363607bc4ac9a3213f8f900f04"</span>];
|
|
<span style="color: #2aa198;">"cb495d05531ffb36b47f07bfde7b29547b60d68a"</span> -> <span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>;
|
|
<span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span> -> <span style="color: #2aa198;">"cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4"</span>;
|
|
<span style="color: #2aa198;">"3992cf3e490b423591805d4c6bc335a34753f9d7"</span> -> <span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>;
|
|
<span style="color: #2aa198;">"ee5c898281c0ba1965a2623e89bdfc1c6a767d4b"</span> -> <span style="color: #2aa198;">"82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5"</span>;
|
|
<span style="color: #2aa198;">"ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b"</span> -> <span style="color: #2aa198;">"ee5c898281c0ba1965a2623e89bdfc1c6a767d4b"</span>;
|
|
<span style="color: #2aa198;">"3992cf3e490b423591805d4c6bc335a34753f9d7"</span> -> <span style="color: #2aa198;">"ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b"</span>;
|
|
<span style="color: #2aa198;">"43c20e67d20b154ae0fbfd54ad946dd188732e83"</span> -> <span style="color: #2aa198;">"3992cf3e490b423591805d4c6bc335a34753f9d7"</span>;
|
|
<span style="color: #2aa198;">"cb495d05531ffb36b47f07bfde7b29547b60d68a"</span> -> <span style="color: #2aa198;">"43c20e67d20b154ae0fbfd54ad946dd188732e83"</span>;
|
|
<span style="color: #2aa198;">"fe2eaeeb6a0f555c12e1304fa4738d2ce465a478"</span> -> <span style="color: #2aa198;">"cb495d05531ffb36b47f07bfde7b29547b60d68a"</span>;
|
|
<span style="color: #2aa198;">"5e0a1de946c0cefa35b007996d9a649e44adec5e"</span> -> <span style="color: #2aa198;">"6b3ccf19c49a57363607bc4ac9a3213f8f900f04"</span>;
|
|
<span style="color: #2aa198;">"43c20e67d20b154ae0fbfd54ad946dd188732e83"</span> -> <span style="color: #2aa198;">"5e0a1de946c0cefa35b007996d9a649e44adec5e"</span>;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
-->
|
|
<!-- Title: git Pages: 1 -->
|
|
<svg width="476pt" height="132pt"
|
|
viewBox="0.00 0.00 476.20 132.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 128)">
|
|
<title>git</title>
|
|
<!-- cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4 -->
|
|
<g id="node1" class="node"><title>cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4</title>
|
|
<polygon fill="none" stroke="black" points="468.2,-124 430.2,-124 430.2,-107 468.2,-107 468.2,-124"/>
|
|
<text text-anchor="middle" x="449.2" y="-113.6" font-family="Times,serif" font-size="8.00">master</text>
|
|
</g>
|
|
<!-- 82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5 -->
|
|
<g id="node2" class="node"><title>82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5</title>
|
|
<polygon fill="none" stroke="black" points="394.2,-86 353.2,-86 353.2,-69 394.2,-69 394.2,-86"/>
|
|
<text text-anchor="middle" x="373.7" y="-75.6" font-family="Times,serif" font-size="8.00">develop</text>
|
|
</g>
|
|
<!-- 82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5->cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4 -->
|
|
<g id="edge2" class="edge"><title>82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5->cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4</title>
|
|
<path fill="none" stroke="black" d="M391.378,-86.1228C403.407,-92.3417 419.574,-100.7 431.588,-106.911"/>
|
|
</g>
|
|
<!-- ee5c898281c0ba1965a2623e89bdfc1c6a767d4b -->
|
|
<g id="node3" class="node"><title>ee5c898281c0ba1965a2623e89bdfc1c6a767d4b</title>
|
|
<polygon fill="none" stroke="black" points="317.2,-49 270.2,-49 270.2,-32 317.2,-32 317.2,-49"/>
|
|
<text text-anchor="middle" x="293.7" y="-38.6" font-family="Times,serif" font-size="8.00">feature-2</text>
|
|
</g>
|
|
<!-- ee5c898281c0ba1965a2623e89bdfc1c6a767d4b->82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5 -->
|
|
<g id="edge4" class="edge"><title>ee5c898281c0ba1965a2623e89bdfc1c6a767d4b->82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5</title>
|
|
<path fill="none" stroke="black" d="M312.791,-49.0815C325.392,-55.059 342.128,-62.9978 354.707,-68.965"/>
|
|
</g>
|
|
<!-- ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b -->
|
|
<g id="node4" class="node"><title>ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b</title>
|
|
<ellipse fill="black" stroke="black" cx="210.7" cy="-40.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b->ee5c898281c0ba1965a2623e89bdfc1c6a767d4b -->
|
|
<g id="edge5" class="edge"><title>ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b->ee5c898281c0ba1965a2623e89bdfc1c6a767d4b</title>
|
|
<path fill="none" stroke="black" d="M216.524,-40.5C226.81,-40.5 251.464,-40.5 269.959,-40.5"/>
|
|
</g>
|
|
<!-- 3992cf3e490b423591805d4c6bc335a34753f9d7 -->
|
|
<g id="node5" class="node"><title>3992cf3e490b423591805d4c6bc335a34753f9d7</title>
|
|
<ellipse fill="black" stroke="black" cx="145.8" cy="-77.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 3992cf3e490b423591805d4c6bc335a34753f9d7->82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5 -->
|
|
<g id="edge3" class="edge"><title>3992cf3e490b423591805d4c6bc335a34753f9d7->82d0efd1a5da2da60f1d01860f0b10b7f5ffa7d5</title>
|
|
<path fill="none" stroke="black" d="M151.518,-77.5C177.496,-77.5 303.702,-77.5 352.956,-77.5"/>
|
|
</g>
|
|
<!-- 3992cf3e490b423591805d4c6bc335a34753f9d7->ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b -->
|
|
<g id="edge6" class="edge"><title>3992cf3e490b423591805d4c6bc335a34753f9d7->ef8dddf2ba63d45c0c1b0b8de0a2293a4a0f6a0b</title>
|
|
<path fill="none" stroke="black" d="M150.927,-75.0723C162.406,-68.3199 194.601,-49.3815 205.801,-42.7936"/>
|
|
</g>
|
|
<!-- 43c20e67d20b154ae0fbfd54ad946dd188732e83 -->
|
|
<g id="node6" class="node"><title>43c20e67d20b154ae0fbfd54ad946dd188732e83</title>
|
|
<ellipse fill="black" stroke="black" cx="99" cy="-77.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 43c20e67d20b154ae0fbfd54ad946dd188732e83->3992cf3e490b423591805d4c6bc335a34753f9d7 -->
|
|
<g id="edge7" class="edge"><title>43c20e67d20b154ae0fbfd54ad946dd188732e83->3992cf3e490b423591805d4c6bc335a34753f9d7</title>
|
|
<path fill="none" stroke="black" d="M104.459,-77.5C113.047,-77.5 131.786,-77.5 140.359,-77.5"/>
|
|
</g>
|
|
<!-- 5e0a1de946c0cefa35b007996d9a649e44adec5e -->
|
|
<g id="node10" class="node"><title>5e0a1de946c0cefa35b007996d9a649e44adec5e</title>
|
|
<ellipse fill="black" stroke="black" cx="145.8" cy="-8.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 43c20e67d20b154ae0fbfd54ad946dd188732e83->5e0a1de946c0cefa35b007996d9a649e44adec5e -->
|
|
<g id="edge11" class="edge"><title>43c20e67d20b154ae0fbfd54ad946dd188732e83->5e0a1de946c0cefa35b007996d9a649e44adec5e</title>
|
|
<path fill="none" stroke="black" d="M102.668,-73.3904C110.58,-61.2051 133.862,-25.3457 141.974,-12.8522"/>
|
|
</g>
|
|
<!-- cb495d05531ffb36b47f07bfde7b29547b60d68a -->
|
|
<g id="node7" class="node"><title>cb495d05531ffb36b47f07bfde7b29547b60d68a</title>
|
|
<ellipse fill="black" stroke="black" cx="52.2" cy="-115.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- cb495d05531ffb36b47f07bfde7b29547b60d68a->cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4 -->
|
|
<g id="edge1" class="edge"><title>cb495d05531ffb36b47f07bfde7b29547b60d68a->cdcc4f7434a915ff6c2c949e74672dcdf8ca36e4</title>
|
|
<path fill="none" stroke="black" d="M57.775,-115.5C71.1596,-115.5 111.404,-115.5 144.8,-115.5 144.8,-115.5 144.8,-115.5 294.7,-115.5 343.468,-115.5 400.952,-115.5 429.77,-115.5"/>
|
|
</g>
|
|
<!-- cb495d05531ffb36b47f07bfde7b29547b60d68a->43c20e67d20b154ae0fbfd54ad946dd188732e83 -->
|
|
<g id="edge8" class="edge"><title>cb495d05531ffb36b47f07bfde7b29547b60d68a->43c20e67d20b154ae0fbfd54ad946dd188732e83</title>
|
|
<path fill="none" stroke="black" d="M56.7154,-112.518C65.0488,-105.45 85.9357,-87.7331 94.3765,-80.5735"/>
|
|
</g>
|
|
<!-- fe2eaeeb6a0f555c12e1304fa4738d2ce465a478 -->
|
|
<g id="node8" class="node"><title>fe2eaeeb6a0f555c12e1304fa4738d2ce465a478</title>
|
|
<ellipse fill="black" stroke="black" cx="5.4" cy="-115.5" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- fe2eaeeb6a0f555c12e1304fa4738d2ce465a478->cb495d05531ffb36b47f07bfde7b29547b60d68a -->
|
|
<g id="edge9" class="edge"><title>fe2eaeeb6a0f555c12e1304fa4738d2ce465a478->cb495d05531ffb36b47f07bfde7b29547b60d68a</title>
|
|
<path fill="none" stroke="black" d="M10.8594,-115.5C19.4466,-115.5 38.1856,-115.5 46.7587,-115.5"/>
|
|
</g>
|
|
<!-- 6b3ccf19c49a57363607bc4ac9a3213f8f900f04 -->
|
|
<g id="node9" class="node"><title>6b3ccf19c49a57363607bc4ac9a3213f8f900f04</title>
|
|
<polygon fill="none" stroke="black" points="234.2,-17 187.2,-17 187.2,-0 234.2,-0 234.2,-17"/>
|
|
<text text-anchor="middle" x="210.7" y="-6.6" font-family="Times,serif" font-size="8.00">feature-1</text>
|
|
</g>
|
|
<!-- 5e0a1de946c0cefa35b007996d9a649e44adec5e->6b3ccf19c49a57363607bc4ac9a3213f8f900f04 -->
|
|
<g id="edge10" class="edge"><title>5e0a1de946c0cefa35b007996d9a649e44adec5e->6b3ccf19c49a57363607bc4ac9a3213f8f900f04</title>
|
|
<path fill="none" stroke="black" d="M151.324,-8.5C158.76,-8.5 174.048,-8.5 187.114,-8.5"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="outline-container-sec-5" class="outline-2">
|
|
<h2 id="sec-5">Things I may add in the future</h2>
|
|
<div class="outline-text-2" id="text-5">
|
|
</div><div id="outline-container-sec-5-1" class="outline-3">
|
|
<h3 id="sec-5-1">Limiting Commits to Graph</h3>
|
|
<div class="outline-text-3" id="text-5-1">
|
|
<p>
|
|
Running this against repos with any substantial history can make the
|
|
graph unwieldy. It'd be a good idea to abstract out the commit list
|
|
fetching, and modify it to support different ways of limiting the
|
|
history to display.
|
|
</p>
|
|
|
|
<p>
|
|
Ideas would include:
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>Specifying commit ranges
|
|
</li>
|
|
<li>Stopping at a common ancestor to all graphed branches (e.g., using
|
|
<code>git-merge-base</code>).
|
|
</li>
|
|
<li>Other git commit limiting options, like searches, showing only merge
|
|
or non-merge commits, etc.
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-5-2" class="outline-3">
|
|
<h3 id="sec-5-2">Collapsing History</h3>
|
|
<div class="outline-text-3" id="text-5-2">
|
|
<p>
|
|
Another means of reducing the size of the resulting graph would be to
|
|
collapse unimportant sections of it. It should be possible to collapse
|
|
a section of the graph, showing a count of skipped nodes.
|
|
</p>
|
|
|
|
<p>
|
|
The difficult part would be determining what parts aren't worth
|
|
drawing. Something like this would be handy, though, for concisely
|
|
graphing the state of multiple ongoing development branches (say, to
|
|
get a picture of what's been going on since the last release, and
|
|
what's still incomplete).
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-dot">digraph <span style="color: #268bd2;">G</span> {
|
|
<span style="color: #268bd2;">rankdir=</span><span style="color: #2aa198;">"LR"</span>;
|
|
<span style="color: #268bd2;">bgcolor=</span><span style="color: #2aa198;">"transparent"</span>;
|
|
node[<span style="color: #268bd2;">width=</span>0.15,<span style="color: #268bd2;">height=</span>0.15,<span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">point</span>];
|
|
edge[<span style="color: #268bd2;">weight=</span>2,<span style="color: #268bd2;">arrowhead=</span><span style="color: #268bd2; font-weight: bold;">none</span>];
|
|
node[<span style="color: #268bd2;">group=</span>main];
|
|
1 -> 2 -> 3 -> 4 -> 5;
|
|
node[<span style="color: #268bd2;">group=</span>branch];
|
|
2 -> 6 -> 7 -> 8 -> 9 -> 10 -> 4;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
-->
|
|
<!-- Title: G Pages: 1 -->
|
|
<svg width="393pt" height="52pt"
|
|
viewBox="0.00 0.00 393.20 51.80" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 47.8)">
|
|
<title>G</title>
|
|
<!-- 1 -->
|
|
<g id="node1" class="node"><title>1</title>
|
|
<ellipse fill="black" stroke="black" cx="5.4" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2 -->
|
|
<g id="node2" class="node"><title>2</title>
|
|
<ellipse fill="black" stroke="black" cx="52.2" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 1->2 -->
|
|
<g id="edge1" class="edge"><title>1->2</title>
|
|
<path fill="none" stroke="black" d="M10.8594,-38.4C19.4466,-38.4 38.1856,-38.4 46.7587,-38.4"/>
|
|
</g>
|
|
<!-- 3 -->
|
|
<g id="node3" class="node"><title>3</title>
|
|
<ellipse fill="black" stroke="black" cx="145.8" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->3 -->
|
|
<g id="edge2" class="edge"><title>2->3</title>
|
|
<path fill="none" stroke="black" d="M57.6181,-38.4C73.0565,-38.4 124.509,-38.4 140.21,-38.4"/>
|
|
</g>
|
|
<!-- 6 -->
|
|
<g id="node6" class="node"><title>6</title>
|
|
<ellipse fill="black" stroke="black" cx="99" cy="-5.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->6 -->
|
|
<g id="edge5" class="edge"><title>2->6</title>
|
|
<path fill="none" stroke="black" d="M57.0196,-35.5864C65.4836,-29.3518 85.7351,-14.4344 94.19,-8.20644"/>
|
|
</g>
|
|
<!-- 4 -->
|
|
<g id="node4" class="node"><title>4</title>
|
|
<ellipse fill="black" stroke="black" cx="333" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 3->4 -->
|
|
<g id="edge3" class="edge"><title>3->4</title>
|
|
<path fill="none" stroke="black" d="M151.378,-38.4C177.001,-38.4 302.379,-38.4 327.582,-38.4"/>
|
|
</g>
|
|
<!-- 5 -->
|
|
<g id="node5" class="node"><title>5</title>
|
|
<ellipse fill="black" stroke="black" cx="379.8" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 4->5 -->
|
|
<g id="edge4" class="edge"><title>4->5</title>
|
|
<path fill="none" stroke="black" d="M338.459,-38.4C347.047,-38.4 365.786,-38.4 374.359,-38.4"/>
|
|
</g>
|
|
<!-- 7 -->
|
|
<g id="node7" class="node"><title>7</title>
|
|
<ellipse fill="black" stroke="black" cx="145.8" cy="-5.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 6->7 -->
|
|
<g id="edge6" class="edge"><title>6->7</title>
|
|
<path fill="none" stroke="black" d="M104.459,-5.4C113.047,-5.4 131.786,-5.4 140.359,-5.4"/>
|
|
</g>
|
|
<!-- 8 -->
|
|
<g id="node8" class="node"><title>8</title>
|
|
<ellipse fill="black" stroke="black" cx="192.6" cy="-5.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 7->8 -->
|
|
<g id="edge7" class="edge"><title>7->8</title>
|
|
<path fill="none" stroke="black" d="M151.259,-5.4C159.847,-5.4 178.586,-5.4 187.159,-5.4"/>
|
|
</g>
|
|
<!-- 9 -->
|
|
<g id="node9" class="node"><title>9</title>
|
|
<ellipse fill="black" stroke="black" cx="239.4" cy="-5.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 8->9 -->
|
|
<g id="edge8" class="edge"><title>8->9</title>
|
|
<path fill="none" stroke="black" d="M198.059,-5.4C206.647,-5.4 225.386,-5.4 233.959,-5.4"/>
|
|
</g>
|
|
<!-- 10 -->
|
|
<g id="node10" class="node"><title>10</title>
|
|
<ellipse fill="black" stroke="black" cx="286.2" cy="-5.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 9->10 -->
|
|
<g id="edge9" class="edge"><title>9->10</title>
|
|
<path fill="none" stroke="black" d="M244.859,-5.4C253.447,-5.4 272.186,-5.4 280.759,-5.4"/>
|
|
</g>
|
|
<!-- 10->4 -->
|
|
<g id="edge10" class="edge"><title>10->4</title>
|
|
<path fill="none" stroke="black" d="M291.02,-8.21356C299.484,-14.4482 319.735,-29.3656 328.19,-35.5936"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-dot">digraph <span style="color: #268bd2;">G</span> {
|
|
<span style="color: #268bd2;">rankdir=</span><span style="color: #2aa198;">"LR"</span>;
|
|
<span style="color: #268bd2;">bgcolor=</span><span style="color: #2aa198;">"transparent"</span>;
|
|
node[<span style="color: #268bd2;">width=</span>0.15,<span style="color: #268bd2;">height=</span>0.15,<span style="color: #268bd2;">shape=</span><span style="color: #268bd2; font-weight: bold;">point</span>];
|
|
edge[<span style="color: #268bd2;">weight=</span>2,<span style="color: #268bd2;">arrowhead=</span><span style="color: #268bd2; font-weight: bold;">none</span>];
|
|
node[<span style="color: #268bd2;">group=</span>main];
|
|
1 -> 2 -> 3 -> 4 -> 5;
|
|
node[<span style="color: #268bd2;">group=</span>branch];
|
|
2 -> 6;
|
|
6 -> 10[<span style="color: #268bd2;">style=</span><span style="color: #268bd2; font-weight: bold;">dashed</span>,<span style="color: #268bd2;">label=</span><span style="color: #2aa198;">"+3"</span>];
|
|
10 -> 4;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
-->
|
|
<!-- Title: G Pages: 1 -->
|
|
<svg width="273pt" height="52pt"
|
|
viewBox="0.00 0.00 272.80 51.80" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 47.8)">
|
|
<title>G</title>
|
|
<!-- 1 -->
|
|
<g id="node1" class="node"><title>1</title>
|
|
<ellipse fill="black" stroke="black" cx="5.4" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2 -->
|
|
<g id="node2" class="node"><title>2</title>
|
|
<ellipse fill="black" stroke="black" cx="53.2" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 1->2 -->
|
|
<g id="edge1" class="edge"><title>1->2</title>
|
|
<path fill="none" stroke="black" d="M10.9589,-38.4C19.7379,-38.4 38.8951,-38.4 47.6595,-38.4"/>
|
|
</g>
|
|
<!-- 3 -->
|
|
<g id="node3" class="node"><title>3</title>
|
|
<ellipse fill="black" stroke="black" cx="132.4" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->3 -->
|
|
<g id="edge2" class="edge"><title>2->3</title>
|
|
<path fill="none" stroke="black" d="M58.798,-38.4C72.5612,-38.4 113.319,-38.4 126.923,-38.4"/>
|
|
</g>
|
|
<!-- 6 -->
|
|
<g id="node6" class="node"><title>6</title>
|
|
<ellipse fill="black" stroke="black" cx="101" cy="-5.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 2->6 -->
|
|
<g id="edge5" class="edge"><title>2->6</title>
|
|
<path fill="none" stroke="black" d="M58.1049,-35.5864C66.7578,-29.3518 87.4613,-14.4344 96.105,-8.20644"/>
|
|
</g>
|
|
<!-- 4 -->
|
|
<g id="node4" class="node"><title>4</title>
|
|
<ellipse fill="black" stroke="black" cx="211.6" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 3->4 -->
|
|
<g id="edge3" class="edge"><title>3->4</title>
|
|
<path fill="none" stroke="black" d="M137.998,-38.4C151.761,-38.4 192.519,-38.4 206.123,-38.4"/>
|
|
</g>
|
|
<!-- 5 -->
|
|
<g id="node5" class="node"><title>5</title>
|
|
<ellipse fill="black" stroke="black" cx="259.4" cy="-38.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 4->5 -->
|
|
<g id="edge4" class="edge"><title>4->5</title>
|
|
<path fill="none" stroke="black" d="M217.159,-38.4C225.938,-38.4 245.095,-38.4 253.86,-38.4"/>
|
|
</g>
|
|
<!-- 10 -->
|
|
<g id="node7" class="node"><title>10</title>
|
|
<ellipse fill="black" stroke="black" cx="163.8" cy="-5.4" rx="5.4" ry="5.4"/>
|
|
</g>
|
|
<!-- 6->10 -->
|
|
<g id="edge6" class="edge"><title>6->10</title>
|
|
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M106.771,-5.4C118.193,-5.4 146.99,-5.4 158.218,-5.4"/>
|
|
<text text-anchor="middle" x="132.4" y="-9.2" font-family="Times,serif" font-size="14.00">+3</text>
|
|
</g>
|
|
<!-- 10->4 -->
|
|
<g id="edge7" class="edge"><title>10->4</title>
|
|
<path fill="none" stroke="black" d="M168.705,-8.21356C177.358,-14.4482 198.061,-29.3656 206.705,-35.5936"/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-5-3" class="outline-3">
|
|
<h3 id="sec-5-3">Clean up and optimize the code a bit</h3>
|
|
<div class="outline-text-3" id="text-5-3">
|
|
<p>
|
|
Some parts of this (particularly, the grouping) are probably pretty
|
|
inefficient. If this turns out to actually be useful, I may take
|
|
another crack at it.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-6" class="outline-2">
|
|
<h2 id="sec-6">Final Code</h2>
|
|
<div class="outline-text-2" id="text-6">
|
|
<p>
|
|
In case anyone would like to use this code for anything, or maybe just
|
|
pick it apart and play around with it, all the Emacs Lisp code in this
|
|
post is collected into a single file below:
|
|
</p>
|
|
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-emacs-lisp"><span style="color: #586e75;">;;; </span><span style="color: #586e75;">git-graph.el --- Generate git-style graphs using graphviz</span>
|
|
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">Copyright (c) 2015 Correl Roush <a href="mailto:correl%40gmail.com"><correl@gmail.com></a></span>
|
|
|
|
<span style="color: #586e75;">;;; </span><span style="color: #586e75;">License:</span>
|
|
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">This program is free software; you can redistribute it and/or modify</span>
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">it under the terms of the GNU General Public License as published by</span>
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">the Free Software Foundation; either version 3, or (at your option)</span>
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">any later version.</span>
|
|
<span style="color: #586e75;">;;</span>
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">This program is distributed in the hope that it will be useful,</span>
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">GNU General Public License for more details.</span>
|
|
<span style="color: #586e75;">;;</span>
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">You should have received a copy of the GNU General Public License</span>
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">along with GNU Emacs; see the file COPYING. If not, write to the</span>
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,</span>
|
|
<span style="color: #586e75;">;; </span><span style="color: #586e75;">Boston, MA 02110-1301, USA.</span>
|
|
|
|
<span style="color: #586e75;">;;; </span><span style="color: #586e75;">Commentary:</span>
|
|
|
|
<span style="color: #586e75;">;;; </span><span style="color: #586e75;">Code:</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/make-node</span> <span style="color: #b58900;">(</span><span style="color: #b6a0e0;">id</span> <span style="color: #b58900;">&optional</span> <span style="color: #a6bb99;">parents</span> <span style="color: #e0d0a0;">options</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #b3c0a7;">list</span> <span style="color: #b6a0e0;">id</span> <span style="color: #a6bb99;">parents</span> <span style="color: #e0d0a0;">options</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/node-id</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #9999bb;">nth</span> <span style="color: #a7aac0;">0</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/node-parents</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #9999bb;">nth</span> <span style="color: #9999bb;">1</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/node-group</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #c0a7bd;">cdr</span> <span style="color: #268bd2;">(</span><span style="color: #bb99b4;">assoc</span> '<span style="color: #a7aac0;">group</span> <span style="color: #6c71c4;">(</span><span style="color: #9999bb;">nth</span> <span style="color: #a6bb99;">2</span> <span style="color: #99bbb4;">node</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/node-label</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #c0a7bd;">cdr</span> <span style="color: #268bd2;">(</span><span style="color: #bb99b4;">assoc</span> '<span style="color: #a7aac0;">label</span> <span style="color: #6c71c4;">(</span><span style="color: #9999bb;">nth</span> <span style="color: #a6bb99;">2</span> <span style="color: #99bbb4;">node</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/+</span> <span style="color: #b58900;">(</span><span style="color: #9999bb;">a</span> <span style="color: #9999bb;">b</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a7aac0;">append</span> <span style="color: #9999bb;">a</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">-remove</span> <span style="color: #6c71c4;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #859900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #bb99b4;">assoc</span> <span style="color: #b58900;">(</span><span style="color: #e0d0a0;">git-graph/node-id</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span> <span style="color: #9999bb;">a</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #9999bb;">b</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-node-id</span> <span style="color: #b58900;">(</span><span style="color: #b6a0e0;">id</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a0d6e0;">format</span> <span style="color: #2aa198;">"\"%s\""</span> <span style="color: #b6a0e0;">id</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-node</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">let</span> <span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #c0afa7;">node-id</span> <span style="color: #859900;">(</span><span style="color: #c0afa7;">git-graph/to-graphviz-node-id</span> <span style="color: #b58900;">(</span><span style="color: #e0d0a0;">git-graph/node-id</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #c0a7bd;">concat</span> <span style="color: #c0afa7;">node-id</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">git-graph/to-graphviz-node--attributes</span> <span style="color: #99bbb4;">node</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #2aa198;">";"</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-node--attributes</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">let</span> <span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">attributes</span> <span style="color: #859900;">(</span><span style="color: #99bbb4;">git-graph/to-graphviz-node--compute-attributes</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #b3c0a7;">and</span> <span style="color: #a3e0a0;">attributes</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #c0a7bd;">concat</span> <span style="color: #2aa198;">"["</span>
|
|
<span style="color: #859900;">(</span><span style="color: #b6a0e0;">mapconcat</span> <span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #268bd2;">(</span><span style="color: #a7aac0;">pair</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #a0d6e0;">format</span> <span style="color: #2aa198;">"%s=\"%s\""</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #99bbb4;">car</span> <span style="color: #a7aac0;">pair</span><span style="color: #6c71c4;">)</span> <span style="color: #6c71c4;">(</span><span style="color: #c0a7bd;">cdr</span> <span style="color: #a7aac0;">pair</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #a3e0a0;">attributes</span>
|
|
<span style="color: #2aa198;">", "</span><span style="color: #859900;">)</span>
|
|
<span style="color: #2aa198;">"]"</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-node--compute-attributes</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">-filter</span> #'<span style="color: #a3e0a0;">identity</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #a7aac0;">append</span> <span style="color: #6c71c4;">(</span><span style="color: #b3c0a7;">and</span> <span style="color: #859900;">(</span><span style="color: #b6a0e0;">git-graph/node-group</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #b3c0a7;">list</span> <span style="color: #b58900;">(</span><span style="color: #a0d6e0;">cons</span> '<span style="color: #a7aac0;">group</span> <span style="color: #268bd2;">(</span><span style="color: #b6a0e0;">git-graph/node-group</span> <span style="color: #99bbb4;">node</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #b3c0a7;">and</span> <span style="color: #859900;">(</span><span style="color: #e0a0bc;">git-graph/node-label</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #b3c0a7;">list</span> <span style="color: #b58900;">(</span><span style="color: #a0d6e0;">cons</span> '<span style="color: #a6bb99;">shape</span> '<span style="color: #bba699;">box</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a0d6e0;">cons</span> '<span style="color: #a7aac0;">label</span> <span style="color: #268bd2;">(</span><span style="color: #e0a0bc;">git-graph/node-label</span> <span style="color: #99bbb4;">node</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-edges</span> <span style="color: #b58900;">(</span><span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">let</span> <span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #c0afa7;">node-id</span> <span style="color: #859900;">(</span><span style="color: #e0d0a0;">git-graph/node-id</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">parents</span> <span style="color: #859900;">(</span><span style="color: #a7c0b9;">git-graph/node-parents</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">-map</span> <span style="color: #6c71c4;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #859900;">(</span><span style="color: #a7c0b9;">parent</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #b3c0a7;">git-graph/to-graphviz-edge</span> <span style="color: #c0afa7;">node-id</span> <span style="color: #a7c0b9;">parent</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #a6bb99;">parents</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/to-graphviz-edge</span> <span style="color: #b58900;">(</span><span style="color: #a3e0a0;">from</span> <span style="color: #e0a0bc;">to</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #c0a7bd;">concat</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #c0afa7;">git-graph/to-graphviz-node-id</span> <span style="color: #e0a0bc;">to</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #2aa198;">" -> "</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #c0afa7;">git-graph/to-graphviz-node-id</span> <span style="color: #a3e0a0;">from</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #2aa198;">";"</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/group-topo</span> <span style="color: #b58900;">(</span><span style="color: #a7aac0;">nodelist</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #c0afa7;">reverse</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #99bbb4;">car</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #859900; font-weight: bold;">-reduce-from</span>
|
|
<span style="color: #859900;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #b58900;">(</span><span style="color: #268bd2;">acc</span> <span style="color: #99bbb4;">node</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">let*</span> <span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">grouped-nodes</span> <span style="color: #859900;">(</span><span style="color: #99bbb4;">car</span> <span style="color: #268bd2;">acc</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">group-stack</span> <span style="color: #859900;">(</span><span style="color: #c0a7bd;">cdr</span> <span style="color: #268bd2;">acc</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #c0afa7;">node-id</span> <span style="color: #859900;">(</span><span style="color: #e0d0a0;">git-graph/node-id</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a7c0b9;">group-from-stack</span> <span style="color: #859900;">(</span><span style="color: #859900; font-weight: bold;">--if-let</span> <span style="color: #2aa198;">(</span><span style="color: #bb99b4;">assoc</span> <span style="color: #c0afa7;">node-id</span> <span style="color: #a6bb99;">group-stack</span><span style="color: #2aa198;">)</span>
|
|
<span style="color: #2aa198;">(</span><span style="color: #c0a7bd;">cdr</span> <span style="color: #268bd2;">it</span><span style="color: #2aa198;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a7aac0;">group</span> <span style="color: #859900;">(</span><span style="color: #a7aac0;">or</span> <span style="color: #a7c0b9;">group-from-stack</span> <span style="color: #c0afa7;">node-id</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">parents</span> <span style="color: #859900;">(</span><span style="color: #a7c0b9;">git-graph/node-parents</span> <span style="color: #99bbb4;">node</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #b6a0e0;">first-parent</span> <span style="color: #859900;">(</span><span style="color: #a0d6e0;">first</span> <span style="color: #a6bb99;">parents</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">if</span> <span style="color: #a7c0b9;">group-from-stack</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #99bbb4;">pop</span> <span style="color: #a6bb99;">group-stack</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">if</span> <span style="color: #6c71c4;">(</span><span style="color: #b3c0a7;">and</span> <span style="color: #b6a0e0;">first-parent</span> <span style="color: #859900;">(</span><span style="color: #9999bb;">not</span> <span style="color: #2aa198;">(</span><span style="color: #bb99b4;">assoc</span> <span style="color: #b6a0e0;">first-parent</span> <span style="color: #a6bb99;">group-stack</span><span style="color: #2aa198;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #6c71c4;">(</span><span style="color: #a6bb99;">push</span> <span style="color: #859900;">(</span><span style="color: #a0d6e0;">cons</span> <span style="color: #b6a0e0;">first-parent</span> <span style="color: #a7aac0;">group</span><span style="color: #859900;">)</span> <span style="color: #a6bb99;">group-stack</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #a0d6e0;">cons</span> <span style="color: #6c71c4;">(</span><span style="color: #a0d6e0;">cons</span> <span style="color: #859900;">(</span><span style="color: #9999bb;">git-graph/make-node</span> <span style="color: #c0afa7;">node-id</span>
|
|
<span style="color: #a6bb99;">parents</span>
|
|
`<span style="color: #2aa198;">(</span><span style="color: #b58900;">(</span><span style="color: #a7aac0;">group</span> <span style="color: #b3c0a7;">.</span> ,<span style="color: #a7aac0;">group</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a7aac0;">label</span> <span style="color: #b3c0a7;">.</span> ,<span style="color: #268bd2;">(</span><span style="color: #e0a0bc;">git-graph/node-label</span> <span style="color: #99bbb4;">node</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span><span style="color: #859900;">)</span>
|
|
<span style="color: #a3e0a0;">grouped-nodes</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #a6bb99;">group-stack</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span>
|
|
<span style="color: #bb99b4;">nil</span>
|
|
<span style="color: #a7aac0;">nodelist</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/git-execute</span> <span style="color: #b58900;">(</span><span style="color: #9999bb;">repo-url</span> <span style="color: #b6a0e0;">command</span> <span style="color: #b58900;">&rest</span> <span style="color: #a6bb99;">args</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">with-temp-buffer</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #bba699;">shell-command</span> <span style="color: #6c71c4;">(</span><span style="color: #a0d6e0;">format</span> <span style="color: #2aa198;">"git -C \"%s\" %s"</span>
|
|
<span style="color: #9999bb;">repo-url</span>
|
|
<span style="color: #859900;">(</span><span style="color: #a7c0b9;">string-join</span> <span style="color: #b58900;">(</span><span style="color: #a0d6e0;">cons</span> <span style="color: #b6a0e0;">command</span> <span style="color: #a6bb99;">args</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #2aa198;">" "</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #a0d6e0;">t</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">buffer-string</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/git-rev-list</span> <span style="color: #b58900;">(</span><span style="color: #9999bb;">repo-url</span> <span style="color: #a6bb99;">head</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">-map</span> <span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">line</span><span style="color: #6c71c4;">)</span> <span style="color: #6c71c4;">(</span><span style="color: #9999bb;">split-string</span> <span style="color: #a3e0a0;">line</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #9999bb;">split-string</span> <span style="color: #6c71c4;">(</span><span style="color: #a3e0a0;">git-graph/git-execute</span>
|
|
<span style="color: #9999bb;">repo-url</span>
|
|
<span style="color: #2aa198;">"rev-list"</span> <span style="color: #2aa198;">"--topo-order"</span> <span style="color: #2aa198;">"--parents"</span> <span style="color: #a6bb99;">head</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #2aa198;">"\n"</span> <span style="color: #a0d6e0;">t</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/git-label</span> <span style="color: #b58900;">(</span><span style="color: #9999bb;">repo-url</span> <span style="color: #a3e0a0;">rev</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">let</span> <span style="color: #268bd2;">(</span><span style="color: #6c71c4;">(</span><span style="color: #bba699;">name</span> <span style="color: #859900;">(</span><span style="color: #bba699;">string-trim</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #a3e0a0;">git-graph/git-execute</span> <span style="color: #9999bb;">repo-url</span>
|
|
<span style="color: #2aa198;">"name-rev"</span> <span style="color: #2aa198;">"--name-only"</span> <span style="color: #a3e0a0;">rev</span><span style="color: #b58900;">)</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span><span style="color: #268bd2;">)</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">unless</span> <span style="color: #6c71c4;">(</span><span style="color: #c0a7bd;">s-contains?</span> <span style="color: #2aa198;">"~"</span> <span style="color: #bba699;">name</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #bba699;">name</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
<span style="color: #2aa198;">(</span><span style="color: #859900; font-weight: bold;">defun</span> <span style="color: #268bd2;">git-graph/git-load</span> <span style="color: #b58900;">(</span><span style="color: #9999bb;">repo-url</span> <span style="color: #a7c0b9;">heads</span><span style="color: #b58900;">)</span>
|
|
<span style="color: #b58900;">(</span><span style="color: #859900; font-weight: bold;">-reduce</span> #'<span style="color: #c0afa7;">git-graph/+</span>
|
|
<span style="color: #268bd2;">(</span><span style="color: #859900; font-weight: bold;">-map</span> <span style="color: #6c71c4;">(</span><span style="color: #859900; font-weight: bold;">lambda</span> <span style="color: #859900;">(</span><span style="color: #a6bb99;">head</span><span style="color: #859900;">)</span>
|
|
<span style="color: #859900;">(</span><span style="color: #a7aac0;">git-graph/git-graph-head</span> <span style="color: #9999bb;">repo-url</span> <span style="color: #a6bb99;">head</span><span style="color: #859900;">)</span><span style="color: #6c71c4;">)</span>
|
|
<span style="color: #a7c0b9;">heads</span><span style="color: #268bd2;">)</span><span style="color: #b58900;">)</span><span style="color: #2aa198;">)</span>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Download: <a href="/files/git-graph.el">git-graph.el</a>
|
|
</p>
|
|
</div>
|
|
</div>
|