Having this code
from dulwich.objects import Blob, Tree, Commit, parse_timezone
from dulwich.repo import Repo
from time import time
repo = Repo.init("myrepo", mkdir=True)
blob = Blob.from_string("my file content\n")
tree = Tree()
tree.add("spam", 0100644, blob.id)
commit = Commit()
commit.tree = tree.id
author = "Flav <[email protected]>"
commit.author = commit.committer = author
commit.commit_time = commit.author_time = int(time())
tz = parse_timezone('+0200')[0]
commit.commit_timezone = commit.author_timezone = tz
commit.encoding = "UTF-8"
commit.message = "initial commit"
o_sto = repo.object_store
o_sto.add_object(blob)
o_sto.add_object(tree)
o_sto.add_object(commit)
repo.refs["HEAD"] = commit.id
I end up with the commit in the history, BUT the created file is pending for deletion (git status
says so).
A git checkout .
fixes it.
My question is: how to do git checkout .
programmatically with dulwich?
Git status says it's deleted because the file doesn't exist in the working copy, that's why checking it out fixes the status.
It looks like there's no support for high-level working copy classes and functions in dulwich yet. You'd have to deal with trees and blobs and unpacking objects.
OK, took the challenge: I could make a basic checkout with Dulwich :
#get repository object of current directory
repo = Repo('.')
#get tree corresponding to the head commit
tree_id = repo["HEAD"].tree
#iterate over tree content, giving path and blob sha.
for entry in repo.object_store.iter_tree_contents(tree_id):
path = entry.in_path(repo.path).path
dulwich.file.ensure_dir_exists(os.path.split(path)[0])
with open(path, 'wb') as file:
#write blob's content to file
file.write(repo[entry.sha].as_raw_string())
It won't delete files that must be deleted, won't care about your index, etc.
See also Mark Mikofski's github project for more complete code based on this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With