|
|
@@ -0,0 +1,84 @@ |
|
|
""" |
|
|
Defines a function `auto_insert` to help with |
|
|
`pygit2.Repository.TreeBuilder`s. |
|
|
|
|
|
Just create the top-level `TreeBuilder`, and it will handle all subtree |
|
|
creation if you give it paths. |
|
|
""" |
|
|
|
|
|
import shutil |
|
|
from tempfile import mkdtemp |
|
|
from pygit2 import init_repository |
|
|
from pygit2 import GIT_FILEMODE_TREE, GIT_FILEMODE_BLOB |
|
|
|
|
|
repo_dir = mkdtemp() |
|
|
repo = init_repository(repo_dir) |
|
|
|
|
|
|
|
|
def auto_insert(repo, treebuilder, path, thing, mode): |
|
|
"""figure out and deal with the necessary subtree structure""" |
|
|
path_parts = path.split('/', 1) |
|
|
if len(path_parts) == 1: # base case |
|
|
treebuilder.insert(path, thing, mode) |
|
|
return treebuilder.write() |
|
|
|
|
|
subtree_name, sub_path = path_parts |
|
|
tree_oid = treebuilder.write() |
|
|
tree = repo.get(tree_oid) |
|
|
try: |
|
|
entry = tree[subtree_name] |
|
|
assert entry.filemode == GIT_FILEMODE_TREE,\ |
|
|
'{} already exists as a blob, not a tree'.format(entry.name) |
|
|
existing_subtree = repo.get(entry.hex) |
|
|
sub_treebuilder = repo.TreeBuilder(existing_subtree) |
|
|
except KeyError: |
|
|
sub_treebuilder = repo.TreeBuilder() |
|
|
|
|
|
subtree_oid = auto_insert(repo, sub_treebuilder, sub_path, thing, mode) |
|
|
treebuilder.insert(subtree_name, subtree_oid, GIT_FILEMODE_TREE) |
|
|
return treebuilder.write() |
|
|
|
|
|
|
|
|
# create the only treebuilder we want to have to deal with |
|
|
root = repo.TreeBuilder() |
|
|
|
|
|
|
|
|
# make something for the tree |
|
|
path = 'some-folder/filename.txt' |
|
|
blob_sha = repo.create_blob('asdf') |
|
|
# throw it in |
|
|
auto_insert(repo, root, path, blob_sha, GIT_FILEMODE_BLOB) |
|
|
|
|
|
|
|
|
# add something more to the same subtree |
|
|
path2 = 'some-folder/another-file.txt' |
|
|
blob2_sha = repo.create_blob('fdsa') |
|
|
auto_insert(repo, root, path2, blob2_sha, GIT_FILEMODE_BLOB) |
|
|
|
|
|
# add something deep |
|
|
path3 = 'very/deeply/nested/deep-file.txt' |
|
|
blob3_sha = repo.create_blob('sup') |
|
|
auto_insert(repo, root, path3, blob3_sha, GIT_FILEMODE_BLOB) |
|
|
|
|
|
# add something to the top |
|
|
path4 = 'top-file.txt' |
|
|
blob4_sha = repo.create_blob('blah') |
|
|
auto_insert(repo, root, path4, blob4_sha, GIT_FILEMODE_BLOB) |
|
|
|
|
|
|
|
|
# did it stick? |
|
|
def print_tree(tree, indent=''): |
|
|
for entry in tree: |
|
|
if entry.filemode == GIT_FILEMODE_TREE: |
|
|
print('{}{}/'.format(indent, entry.name)) |
|
|
subtree = repo.get(entry.hex) |
|
|
print_tree(subtree, indent=' {}'.format(indent)) |
|
|
else: |
|
|
print('{}{}'.format(indent, entry.name)) |
|
|
tree_oid = root.write() |
|
|
tree = repo.get(tree_oid) |
|
|
print_tree(tree) |
|
|
|
|
|
|
|
|
# housekeeping: clean up the temp repo |
|
|
shutil.rmtree(repo_dir) |