Skip to content

Instantly share code, notes, and snippets.

@Akarys42
Last active February 2, 2023 20:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Akarys42/47085d16978947039279d75e1773725e to your computer and use it in GitHub Desktop.
Save Akarys42/47085d16978947039279d75e1773725e to your computer and use it in GitHub Desktop.
The main script created during Ambre 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__", "my_commit.py"}
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():
folder.mkdir()
# Write the file
with open(folder / hash_[2:], "wb") as file:
file.write(compressed)
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", file.read())
def write_tree(path: Path) -> str:
"""Write the tree to the database and return its SHA."""
lines = []
children = list(path.iterdir())
children.sort()
for child in children:
# Skip some problematic files.
if child.name in EXCLUDED_FILES:
continue
# 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"
else:
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, child.name.encode("utf8"), hash_bytes)
lines.append(line)
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}
author {AUTHOR_IDENTITY} {COMMIT_TIMESTAMP}
committer {AUTHOR_IDENTITY} {COMMIT_TIMESTAMP}
{message}
""").encode("utf8")
return write_object("commit", commit)
if __name__ == "__main__":
if len(sys.argv) == 1:
print("my_commit.py: no message provided.")
exit(1)
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