Add --show-objects arg to log

So that we see the objects pointed to by commits as well as the commits themselves
This commit is contained in:
Nathan McRae 2024-07-14 20:28:34 -07:00
parent 7a63ccd990
commit 3a13d25e9c

View File

@ -457,15 +457,16 @@ argsp.add_argument("commit",
nargs="?", nargs="?",
help="Commit to start at.") help="Commit to start at.")
argsp.add_argument("--show-objects", action="store_true", help="Show objects along with commit DAG")
def cmd_log(args): def cmd_log(args):
repo = repo_find() repo = repo_find()
print(log_graphviz(repo, args.commit)) print(log_graphviz(repo, args.commit, args.show_objects))
def log_graphviz_recurse(repo, sha, seen): def log_graphviz_recurse(repo, sha, seen, show_objects):
if sha in seen: if sha in seen:
return return
seen.add(sha)
commit = object_read(repo, sha) commit = object_read(repo, sha)
short_hash = sha[0:8] short_hash = sha[0:8]
@ -475,6 +476,11 @@ def log_graphviz_recurse(repo, sha, seen):
if "\n" in message: # keep only the first line if "\n" in message: # keep only the first line
message = message[:message.index("\n")] message = message[:message.index("\n")]
if show_objects:
for line in graph_objects(repo, sha, seen, True):
yield f" {line}\n"
else:
yield f" c_{sha} [label=\"{sha[0:7]}: {message}\"]" yield f" c_{sha} [label=\"{sha[0:7]}: {message}\"]"
assert commit.fmt==b'commit' assert commit.fmt==b'commit'
@ -489,15 +495,17 @@ def log_graphviz_recurse(repo, sha, seen):
for p in parents: for p in parents:
p = p.decode("ascii") p = p.decode("ascii")
# Commits are also linked to parents in graph_objects
if not show_objects:
yield f" c_{sha} -> c_{p}" yield f" c_{sha} -> c_{p}"
yield from log_graphviz_recurse(repo, p, seen) yield from log_graphviz_recurse(repo, p, seen, show_objects)
def log_graphviz(repo, sha): def log_graphviz(repo, sha, show_objects):
seen = set() seen = set()
graph = "digraph wyaglog{\n" graph = "digraph wyaglog{\n"
graph += " node[shape=rect]\n" graph += " node[shape=rect]\n"
for line in log_graphviz_recurse(repo, object_find(repo, sha), seen): for line in log_graphviz_recurse(repo, object_find(repo, sha), seen, show_objects):
graph += " " + line + "\n" graph += " " + line + "\n"
graph += "}" graph += "}"
@ -1484,12 +1492,11 @@ def tree_from_index(repo, index, commit_map, author, commit_time, message):
if subcommit == None or subcommit.kvlm[b'tree'] != sha.encode('ascii'): if subcommit == None or subcommit.kvlm[b'tree'] != sha.encode('ascii'):
new_subcommit = commit_create(repo, new_subcommit = commit_create(repo,
sha, sha,
subcommit, subcommit_hash,
author, author,
commit_time, commit_time,
message) message)
else: else:
# Problem, subcommit is not a hash, but we need a hash
new_subcommit = subcommit_hash new_subcommit = subcommit_hash
parent = os.path.dirname(path).replace("\\", "/") parent = os.path.dirname(path).replace("\\", "/")
@ -1560,10 +1567,10 @@ argsp.add_argument("object",
metavar="object", metavar="object",
help="The object the graph will start from") help="The object the graph will start from")
def graph_objects_tree(repo, sha, seen): def graph_objects_tree(repo, sha, seen, commit_parents=False):
if sha in seen: if sha in seen:
return return
seen.append(sha) seen.add(sha)
yield f"t_{sha} [label=\"tree {sha[0:7]}\"]" yield f"t_{sha} [label=\"tree {sha[0:7]}\"]"
# TODO: inefficient # TODO: inefficient
@ -1588,28 +1595,30 @@ def graph_objects_tree(repo, sha, seen):
yield from graph_objects_tree(repo, item.sha, seen) yield from graph_objects_tree(repo, item.sha, seen)
if type == "commit" or type == "subcommit": if type == "commit" or type == "subcommit":
yield f"t_{sha} -> c_{item.sha}" yield f"t_{sha} -> c_{item.sha}"
yield from graph_objects(repo, item.sha, seen) yield from graph_objects(repo, item.sha, seen, commit_parents)
if type == "blob": if type == "blob":
yield f"b_{item.sha} [label=\"{item.sha[0:7]} {item.path}\"]" yield f"b_{item.sha} [label=\"{item.sha[0:7]} {item.path}\"]"
yield f"t_{sha} -> b_{item.sha}" yield f"t_{sha} -> b_{item.sha}"
def graph_objects(repo, sha, seen): def graph_objects(repo, sha, seen, commit_parents=False):
if sha in seen: if sha in seen:
return return
seen.append(sha) seen.add(sha)
obj = object_read(repo, sha) obj = object_read(repo, sha)
match obj.fmt: match obj.fmt:
case b"commit": # case b"commit":
message = obj.kvlm[None] message = obj.kvlm[None]
yield f"c_{sha} [label=\"{sha[0:7]}: {message.decode('utf8')}\"]" yield f"c_{sha} [label=\"commit {sha[0:7]}\n {message.decode('utf8')}\"]"
tree_sha = obj.kvlm[b"tree"].decode("ascii") tree_sha = obj.kvlm[b"tree"].decode("ascii")
yield f"c_{sha} -> t_{tree_sha}" yield f"c_{sha} -> t_{tree_sha}"
yield from graph_objects_tree(repo, tree_sha, seen) yield from graph_objects_tree(repo, tree_sha, seen, commit_parents)
if commit_parents and b'parent' in obj.kvlm.keys():
yield f"c_{sha} -> c_{obj.kvlm[b'parent'].decode('ascii')}"
case b"tree": case b"tree":
yield from graph_objects_tree(repo, sha, seen) yield from graph_objects_tree(repo, sha, seen, commits_parents)
def cmd_graph_objects(args): def cmd_graph_objects(args):
repo = repo_find() repo = repo_find()
@ -1622,7 +1631,7 @@ def cmd_graph_objects(args):
obj_sha = object_find(repo, obj_name) obj_sha = object_find(repo, obj_name)
graph = "digraph objectgraph{\n" graph = "digraph objectgraph{\n"
graph += " node[shape=rect]\n" graph += " node[shape=rect]\n"
for str in graph_objects(repo, obj_sha, list()): for str in graph_objects(repo, obj_sha, set()):
graph += " " + str + "\n" graph += " " + str + "\n"
graph += "}" graph += "}"