Add graph-objects command
This commit is contained in:
parent
cc32d87d4d
commit
e7838a5294
76
libwyag.py
76
libwyag.py
@ -38,6 +38,7 @@ def main(argv=sys.argv[1:]):
|
||||
case "show-ref" : cmd_show_ref(args)
|
||||
case "status" : cmd_status(args)
|
||||
case "tag" : cmd_tag(args)
|
||||
case "graph-objects" : cmd_graph_objects(args)
|
||||
case _ : print("Bad command.")
|
||||
|
||||
class GitRepository (object):
|
||||
@ -1542,3 +1543,78 @@ def cmd_commit(args):
|
||||
else: # Otherwise, we update HEAD itself.
|
||||
with open(repo_file(repo, "HEAD"), "w") as fd:
|
||||
fd.write(commit + "\n")
|
||||
|
||||
argsp = argsubparsers.add_parser("graph-objects", help="Show git objects in a dot graph")
|
||||
|
||||
argsp.add_argument("object",
|
||||
nargs="?",
|
||||
metavar="object",
|
||||
help="The object the graph will start from")
|
||||
|
||||
def graph_objects_tree(repo, sha, seen):
|
||||
if sha in seen:
|
||||
return
|
||||
seen.append(sha)
|
||||
|
||||
yield f"t_{sha} [label=\"tree {sha[0:7]}\"]"
|
||||
# TODO: inefficient
|
||||
obj = object_read(repo, sha)
|
||||
|
||||
for item in obj.items:
|
||||
if len(item.mode) == 5:
|
||||
type = item.mode[0:1]
|
||||
else:
|
||||
type = item.mode[0:2]
|
||||
|
||||
match type:
|
||||
case b'04': type = "tree"
|
||||
case b'10': type = "blob"
|
||||
case b'12': type = "blob" # a symlink
|
||||
case b'16': type = "commit" # a submodule
|
||||
case b'sc': type = "subcommit"
|
||||
case _: raise Exception(f"Weird tree leaf mode {item.mode}")
|
||||
|
||||
if type == "tree":
|
||||
yield f"t_{sha} -> t_{item.sha}"
|
||||
yield from graph_objects_tree(repo, item.sha, seen)
|
||||
if type == "commit" or type == "subcommit":
|
||||
yield f"t_{sha} -> c_{item.sha}"
|
||||
yield from graph_objects(repo, item.sha, seen)
|
||||
if type == "blob":
|
||||
yield f"b_{item.sha} [label=\"{item.sha[0:7]} {item.path}\"]"
|
||||
yield f"t_{sha} -> b_{item.sha}"
|
||||
|
||||
|
||||
def graph_objects(repo, sha, seen):
|
||||
if sha in seen:
|
||||
return
|
||||
seen.append(sha)
|
||||
|
||||
obj = object_read(repo, sha)
|
||||
|
||||
match obj.fmt:
|
||||
case b"commit": #
|
||||
message = obj.kvlm[None]
|
||||
yield f"c_{sha} [label=\"{sha[0:7]}: {message.decode('utf8')}\"]"
|
||||
tree_sha = obj.kvlm[b"tree"].decode("ascii")
|
||||
yield f"c_{sha} -> t_{tree_sha}"
|
||||
yield from graph_objects_tree(repo, tree_sha, seen)
|
||||
case b"tree":
|
||||
yield from graph_objects_tree(repo, sha, seen)
|
||||
|
||||
def cmd_graph_objects(args):
|
||||
repo = repo_find()
|
||||
|
||||
if args.object == None:
|
||||
obj_name = "HEAD"
|
||||
else:
|
||||
obj_name = args.object
|
||||
|
||||
obj_sha = object_find(repo, obj_name)
|
||||
graph = "digraph objectgraph{\n"
|
||||
graph += " node[shape=rect]\n"
|
||||
for str in graph_objects(repo, obj_sha, list()):
|
||||
graph += " " + str + "\n"
|
||||
graph += "}"
|
||||
|
||||
print(graph)
|
||||
|
Loading…
Reference in New Issue
Block a user