def inventory_to_tree_and_blobs(repo, mapping, revision_id): stack = [] cur = "" tree = Tree() inv = repo.get_inventory(revision_id) for path, entry in inv.iter_entries(): while stack and not path.startswith(cur): tree.serialize() sha = tree.sha().hexdigest() yield sha, tree t = (stat.S_IFDIR, splitpath(cur)[-1:][0].encode('UTF-8'), sha) cur, tree = stack.pop() tree.add(*t) if type(entry) == InventoryDirectory: stack.append((cur, tree)) cur = path tree = Tree() if type(entry) == InventoryFile: #FIXME: We can make potentially make this Lazy to avoid shaing lots of stuff # and having all these objects in memory at once blob = Blob() _, blob._text = repo.iter_files_bytes([(entry.file_id, revision_id, path)]).next() sha = blob.sha().hexdigest() yield sha, blob name = splitpath(path)[-1:][0].encode('UTF-8') mode = stat.S_IFREG | 0644 if entry.executable: mode |= 0111 tree.add(mode, name, sha) while len(stack) > 1: tree.serialize() sha = tree.sha().hexdigest() yield sha, tree t = (stat.S_IFDIR, splitpath(cur)[-1:][0].encode('UTF-8'), sha) cur, tree = stack.pop() tree.add(*t) tree.serialize() yield tree.sha().hexdigest(), tree
store = repo.object_store print("Object store: {}".format(store)) store.add_object(blob) print("Added one object") # notes: # - single object file in .git/objects now # - "git cat-file -p <hash>": see our file! # - file is compressed (hexdump -C .git/objects/*) # now lets create a real "tree" object so we can give our Blob a # filename tree = Tree() tree.add(b"a_file.txt", 0o100644, blob.id) print("Tree: {}".format(tree.sha().hexdigest())) # note: still not "in" the object repository store.add_object(tree) # From a user perpective, Trees live in Commit objects commit = Commit() commit.tree = tree commit.author = commit.committer = b"meejah <*****@*****.**>" commit.commit_time = commit.author_time = int(time()) # seconds since epoch commit.commit_timezone = commit.author_timezone = -7 * ( 60 * 60) # seconds offset; MST commit.encoding = b"utf8" commit.message = b"The beginning" # no commit.parents because this is the first Commit # again, not in the object store yet