Attempt conversion to subcommit structure
This commit is contained in:
parent
3f49d9f7db
commit
fad314edd8
90
libwyag.py
90
libwyag.py
@ -581,13 +581,14 @@ def ls_tree(repo, ref, recursive=None, prefix=""):
|
||||
type = item.mode[0:2]
|
||||
|
||||
match type:
|
||||
case b'04': type = "tree"
|
||||
case b'04': raise Exception("Trees should point to subcommits, not other trees")
|
||||
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=='tree'): # This is a leaf
|
||||
if not (recursive and type=='subcommit'): # 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
|
||||
@ -596,8 +597,11 @@ def ls_tree(repo, ref, recursive=None, prefix=""):
|
||||
item.sha,
|
||||
join_path(prefix, item.path)
|
||||
))
|
||||
else: # This is a branch (vs. leaf), recurse
|
||||
ls_tree(repo, item.sha, recursive, join_path(prefix, item.path))
|
||||
else: # This is a 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))
|
||||
|
||||
|
||||
argsp = argsubparsers.add_parser("checkout", help="Checkout a commit inside of a directory.")
|
||||
|
||||
@ -1112,13 +1116,19 @@ def tree_to_dict(repo, ref, prefix=""):
|
||||
# We read the object to extract its type (this is uselessly
|
||||
# expensive: we could just open it as a file and read the
|
||||
# first few bytes)
|
||||
is_subtree = leaf.mode.startswith(b'04')
|
||||
if (leaf.mode.startswith(b'04')):
|
||||
raise Exception("Tree should not be child of tree")
|
||||
|
||||
is_subcommit = leaf.mode.startswitch(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,
|
||||
# so a subdir)
|
||||
if is_subtree:
|
||||
ret.update(tree_to_dict(repo, leaf.sha, full_path))
|
||||
if is_subcommit:
|
||||
commit_obj = object_read(repo, leaf.sha)
|
||||
tree_sha = commit_obj.kvlm[b'tree'].decode("ascii")
|
||||
|
||||
ret.update(tree_to_dict(repo, tree_sha, full_path))
|
||||
else:
|
||||
ret[full_path] = leaf.sha
|
||||
|
||||
@ -1367,7 +1377,42 @@ def gitconfig_user_get(config):
|
||||
return f"{config['user']['name']} <{config['user']['email']}>"
|
||||
return None
|
||||
|
||||
def tree_from_index(repo, index):
|
||||
def create_commit_map(repo, commit):
|
||||
commit_map = dict()
|
||||
|
||||
create_commit_map_recurse(repo, commit, commit_map, "")
|
||||
|
||||
return commit_map
|
||||
|
||||
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."""
|
||||
|
||||
tree_sha = commit.kvlm["tree"].decode('ascii')
|
||||
obj = object_read(repo, tree_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': raise Exception("Trees should point to subcommits, not other trees")
|
||||
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 == "subcommit":
|
||||
fullpath = f"{path}/{item.path}"
|
||||
subcommit = object_read(repo, item.sha)
|
||||
commit_map[fullpath] = subcommit
|
||||
|
||||
create_commit_map_recurse(repo, subcommit, commit_map, fullpath)
|
||||
|
||||
|
||||
def tree_from_index(repo, index, commit_map, author, commit_time, message):
|
||||
contents = dict()
|
||||
contents[""] = list()
|
||||
|
||||
@ -1411,6 +1456,15 @@ def tree_from_index(repo, index):
|
||||
|
||||
sha = object_write(tree, repo)
|
||||
|
||||
subcommit = commit_map[path]
|
||||
|
||||
new_subcommit = commit_create(repo,
|
||||
sha,
|
||||
subcommit,
|
||||
author,
|
||||
commit_time,
|
||||
message)
|
||||
|
||||
parent = os.path.dirname(path).replace("\\", "/")
|
||||
base = os.path.basename(path)
|
||||
contents[parent].append((base, sha))
|
||||
@ -1441,13 +1495,25 @@ def commit_create(repo, tree, parent, author, timestamp, message):
|
||||
def cmd_commit(args):
|
||||
repo = repo_find()
|
||||
index = index_read(repo)
|
||||
tree = tree_from_index(repo, index)
|
||||
root_commit = object_find(repo, "HEAD")
|
||||
|
||||
commit_time = datetime.now()
|
||||
author = gitconfig_user_get(gitconfig_read())
|
||||
|
||||
commit_map = create_commit_map(repo, root_commit)
|
||||
|
||||
tree = tree_from_index(repo,
|
||||
index,
|
||||
commit_map,
|
||||
author,
|
||||
commit_time,
|
||||
args.message)
|
||||
|
||||
commit = commit_create(repo,
|
||||
tree,
|
||||
object_find(repo, "HEAD"),
|
||||
gitconfig_user_get(gitconfig_read()),
|
||||
datetime.now(),
|
||||
root_commit,
|
||||
author,
|
||||
commit_time,
|
||||
args.message)
|
||||
|
||||
# Update HEAD so our commit is now the tip of the active branch.
|
||||
|
Loading…
Reference in New Issue
Block a user