Compare commits

...

2 Commits

Author SHA1 Message Date
b854b4fa18 Render graph 2024-05-22 16:52:44 +02:00
2362d69673 Add change 28 to instructions 2024-05-22 16:52:14 +02:00
2 changed files with 33 additions and 4 deletions

18
how_to/Change_28.md Normal file
View File

@@ -0,0 +1,18 @@
- k: Render graph
`k` is supposed to be a visualization tool, but so far we've just printed a
bunch of OIDs... Now comes the visualization part!
There's a convenient file format called "dot" that can describe a graph. This is
a textual format. We'll generate a graph of all commits and refs in dot format
and then visualize it using the "dot" utility that comes with Graphviz.
(If you're unfamiliar with dot or Graphviz please look it up online.)
The graph will contain a node for each commit, that points to the parent commit.
The graph will also contain a node for each ref, which points to the relevant
commit.
At this point, `ugit k` is fully functional and I encourage you to play with it.
Create a crazy branching history and a bunch of tags and see for yourself that
`ugit k` can draw all that visually.

View File

@@ -1,4 +1,5 @@
import argparse import argparse
import subprocess
import sys import sys
import textwrap import textwrap
@@ -110,14 +111,24 @@ def tag(args):
def k(args): def k(args):
dot = "digraph commits {\n"
oids = set() oids = set()
for refname, ref in data.iter_refs(): for refname, ref in data.iter_refs():
print(refname, ref) dot += f"'{refname}' [shape=note]\n"
dot += f"'{refname}' -> '{ref}'\n"
oids.add(ref) oids.add(ref)
for oid in base.iter_commits_and_parents(oids): for oid in base.iter_commits_and_parents(oids):
commit = base.get_commit(oid) commit = base.get_commit(oid)
print(oid) dot += f"'{oid}' [shape=box style=filled label='{oid[:10]}']\n"
if commit.parent: if commit.parent:
print("Parent", commit.parent) dot += f"'{oid}' -> '{commit.parent}'\n"
# TODO visualize refs
dot += "}"
print(dot)
with subprocess.Popen(
["dot", "-Tgtk", "/dev/stdin"], stdin=subprocess.PIPE
) as proc:
proc.communicate(dot.encode())