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]
|
type = item.mode[0:2]
|
||||||
|
|
||||||
match type:
|
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'10': type = "blob"
|
||||||
case b'12': type = "blob" # a symlink
|
case b'12': type = "blob" # a symlink
|
||||||
case b'16': type = "commit" # a submodule
|
case b'16': type = "commit" # a submodule
|
||||||
|
case b'sc': type = "subcommit"
|
||||||
case _: raise Exception(f"Weird tree leaf mode {item.mode}")
|
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(
|
print("{0} {1} {2}\t{3}".format(
|
||||||
"0" * (6 - len(item.mode)) + item.mode.decode("ascii"),
|
"0" * (6 - len(item.mode)) + item.mode.decode("ascii"),
|
||||||
# Git's ls-tree displays the type
|
# Git's ls-tree displays the type
|
||||||
|
@ -596,8 +597,11 @@ def ls_tree(repo, ref, recursive=None, prefix=""):
|
||||||
item.sha,
|
item.sha,
|
||||||
join_path(prefix, item.path)
|
join_path(prefix, item.path)
|
||||||
))
|
))
|
||||||
else: # This is a branch (vs. leaf), recurse
|
else: # This is a subcommit
|
||||||
ls_tree(repo, item.sha, recursive, join_path(prefix, item.path))
|
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.")
|
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
|
# We read the object to extract its type (this is uselessly
|
||||||
# expensive: we could just open it as a file and read the
|
# expensive: we could just open it as a file and read the
|
||||||
# first few bytes)
|
# 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
|
# 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,
|
# blob, so a regular file), or recurse (if it's another tree,
|
||||||
# so a subdir)
|
# so a subdir)
|
||||||
if is_subtree:
|
if is_subcommit:
|
||||||
ret.update(tree_to_dict(repo, leaf.sha, full_path))
|
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:
|
else:
|
||||||
ret[full_path] = leaf.sha
|
ret[full_path] = leaf.sha
|
||||||
|
|
||||||
|
@ -1367,7 +1377,42 @@ def gitconfig_user_get(config):
|
||||||
return f"{config['user']['name']} <{config['user']['email']}>"
|
return f"{config['user']['name']} <{config['user']['email']}>"
|
||||||
return None
|
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 = dict()
|
||||||
contents[""] = list()
|
contents[""] = list()
|
||||||
|
|
||||||
|
@ -1411,6 +1456,15 @@ def tree_from_index(repo, index):
|
||||||
|
|
||||||
sha = object_write(tree, repo)
|
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("\\", "/")
|
parent = os.path.dirname(path).replace("\\", "/")
|
||||||
base = os.path.basename(path)
|
base = os.path.basename(path)
|
||||||
contents[parent].append((base, sha))
|
contents[parent].append((base, sha))
|
||||||
|
@ -1441,13 +1495,25 @@ def commit_create(repo, tree, parent, author, timestamp, message):
|
||||||
def cmd_commit(args):
|
def cmd_commit(args):
|
||||||
repo = repo_find()
|
repo = repo_find()
|
||||||
index = index_read(repo)
|
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,
|
commit = commit_create(repo,
|
||||||
tree,
|
tree,
|
||||||
object_find(repo, "HEAD"),
|
root_commit,
|
||||||
gitconfig_user_get(gitconfig_read()),
|
author,
|
||||||
datetime.now(),
|
commit_time,
|
||||||
args.message)
|
args.message)
|
||||||
|
|
||||||
# Update HEAD so our commit is now the tip of the active branch.
|
# Update HEAD so our commit is now the tip of the active branch.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user