Skip to content

Instantly share code, notes, and snippets.

Last active Nov 27, 2021
What would you like to do?
The main script created during Matteo Bertucci's talk "Learn Python automation by recreating Git Commit from scratch" at EuroPython 2021.
from hashlib import sha1
from textwrap import dedent
from pathlib import Path
import sys
import zlib
OBJECT_PATH = Path(".git/objects")
EXCLUDED_FILES = {".git", "__pycache__", ""}
AUTHOR_IDENTITY = "Example User <example@localhost>"
COMMIT_TIMESTAMP = "1483920000 +0000"
def write_object(type_: str, content: bytes) -> str:
Write down the object with the provided content and type to
the Git database and returns its hash
store = b"%s %d\0%s" % (type_.encode("utf8"), len(content), content)
hash_ = sha1(store).hexdigest()
compressed = zlib.compress(store)
folder = OBJECT_PATH / hash_[:2]
# Make sure that the folder exists
if not folder.exists():
# Write the file
with open(folder / hash_[2:], "wb") as file:
return hash_
def write_blob(path: Path) -> str:
"""Write the file to the database as a blob and return its SHA."""
with open(path, "rb") as file:
return write_object("blob",
def write_tree(path: Path) -> str:
"""Write the tree to the database and return its SHA."""
lines = []
children = list(path.iterdir())
for child in children:
# Skip some problematic files.
# Register the file or folder to the database and add it to this tree
if child.is_dir():
hash_ = write_tree(child)
mode = b"40000"
hash_ = write_blob(child)
mode = b"100644"
# Create the line for this object
hash_bytes = bytes.fromhex(hash_)
line = b"%s %s\0%s" % (mode,"utf8"), hash_bytes)
content = b"".join(lines)
return write_object("tree", content)
def write_commit(message: str) -> str:
"""Write the commit to the database and return its SHA."""
tree = write_tree(Path("."))
commit = dedent(f"""\
tree {tree}
return write_object("commit", commit)
if __name__ == "__main__":
if len(sys.argv) == 1:
print(" no message provided.")
message = " ".join(sys.argv[1:])
hash_ = write_commit(message)
print(f"Created commit {hash_} !")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment