Fix some bugs

This commit is contained in:
Nathan McRae 2024-07-13 14:23:07 -07:00
parent fad314edd8
commit 3d08e348db

View File

@ -581,14 +581,14 @@ def ls_tree(repo, ref, recursive=None, prefix=""):
type = item.mode[0:2]
match type:
case b'04': raise Exception("Trees should point to subcommits, not other trees")
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 not (recursive and type=='subcommit'): # This is a leaf
if not (recursive and type=='tree'): # This is a leaf
print("{0} {1} {2}\t{3}".format(
"0" * (6 - len(item.mode)) + item.mode.decode("ascii"),
# Git's ls-tree displays the type
@ -597,10 +597,12 @@ def ls_tree(repo, ref, recursive=None, prefix=""):
item.sha,
join_path(prefix, item.path)
))
else: # This is a subcommit
if type=='subcommit':
commit_obj = object_read(repo, item.sha)
tree_sha = commit_obj.kvlm[b'tree'].decode("ascii")
ls_tree(repo, tree_sha, recursive, join_path(prefix, item.path))
else: # This is a tree
ls_tree(repo, item.sha, recursive, join_path(prefix, item.path))
argsp = argsubparsers.add_parser("checkout", help="Checkout a commit inside of a directory.")
@ -1119,7 +1121,7 @@ def tree_to_dict(repo, ref, prefix=""):
if (leaf.mode.startswith(b'04')):
raise Exception("Tree should not be child of tree")
is_subcommit = leaf.mode.startswitch(b'sc')
is_subcommit = leaf.mode.startswith(b'sc')
# Depending on the type, we either store the path (if it's a
# blob, so a regular file), or recurse (if it's another tree,
@ -1386,9 +1388,10 @@ def create_commit_map(repo, commit):
def create_commit_map_recurse(repo, commit, commit_map, path):
"""From a root commit, walk down the tree of subcommits. Returns a dict mapping
directory paths to commit objects. Note: doesn't include root commit."""
directory paths to (commit hash, commit objects).
Note: doesn't include root commit."""
tree_sha = commit.kvlm["tree"].decode('ascii')
tree_sha = commit.kvlm[b"tree"].decode('ascii')
obj = object_read(repo, tree_sha)
for item in obj.items:
if len(item.mode) == 5:
@ -1405,9 +1408,12 @@ def create_commit_map_recurse(repo, commit, commit_map, path):
case _: raise Exception(f"Weird tree leaf mode {item.mode}")
if type == "subcommit":
if path == "":
fullpath = item.path
else:
fullpath = f"{path}/{item.path}"
subcommit = object_read(repo, item.sha)
commit_map[fullpath] = subcommit
commit_map[fullpath] = (item.sha, subcommit)
create_commit_map_recurse(repo, subcommit, commit_map, fullpath)
@ -1450,24 +1456,31 @@ def tree_from_index(repo, index, commit_map, author, commit_time, message):
leaf_mode = f"{entry.mode_type:02o}{entry.mode_perms:04o}".encode("ascii")
leaf = GitTreeLeaf(mode=leaf_mode, path=os.path.basename(entry.name), sha=entry.sha)
else: # Tree. We've stored it as a pair: (basename, SHA)
leaf = GitTreeLeaf(mode=b"040000", path=entry[0], sha=entry[1])
leaf = GitTreeLeaf(mode=b"sc0000", path=entry[0], sha=entry[1])
tree.items.append(leaf)
sha = object_write(tree, repo)
subcommit = commit_map[path]
if path in commit_map:
(subcommit_hash, subcommit) = commit_map[path]
else:
subcommit = None
if subcommit == None or subcommit.kvlm[b'tree'] != sha.encode('ascii'):
new_subcommit = commit_create(repo,
sha,
subcommit,
author,
commit_time,
message)
else:
# Problem, subcommit is not a hash, but we need a hash
new_subcommit = subcommit_hash
parent = os.path.dirname(path).replace("\\", "/")
base = os.path.basename(path)
contents[parent].append((base, sha))
contents[parent].append((base, new_subcommit))
return sha
@ -1495,7 +1508,8 @@ def commit_create(repo, tree, parent, author, timestamp, message):
def cmd_commit(args):
repo = repo_find()
index = index_read(repo)
root_commit = object_find(repo, "HEAD")
root_commit_sha = object_find(repo, "HEAD")
root_commit = object_read(repo, root_commit_sha)
commit_time = datetime.now()
author = gitconfig_user_get(gitconfig_read())
@ -1511,7 +1525,7 @@ def cmd_commit(args):
commit = commit_create(repo,
tree,
root_commit,
root_commit_sha,
author,
commit_time,
args.message)