Owner: @DanisLol
Module: 3 - Commits & branching
File you own: minigit/commits.py
Week: 1 of 10 - Contract & Skeletons
What "skeleton week" means
- no real branch switching, no merging yet -> Weeks 4-5
- you depend on Modules 1 and 2 -> do not wait, stub both (step 11)
Interface contract - exact signatures, do not change alone
class CommitManager:
create_commit(tree_hash, parents: list[str], author, message) -> str
create_branch(name, commit_hash) -> None switch_branch(name) -> None
list_branches() -> list[str] merge(branch_name) -> str | None
- a ref = a text file whose whole content is one commit hash ->
.minigit/refs/heads/<branch>
- HEAD =
"ref: refs/heads/main" (symbolic) or a raw hash (detached)
- parents: 0 = root commit, 1 = normal, 2 = merge
Steps
- Setup (once): clone,
cd mini-git, scripts/init.sh, skim README.md + minigit/errors.py
- Branch
week1/m3-commit-manager-skeleton
__init__(self, repo_path=".", store=None, tree=None) -> self.root, store or ObjectStore(...), tree or WorkingTree(...), self._refs: dict[str, str] = {}, self._head = "main"
- the
store= / tree= arguments are the important part: fakes now, real modules later, no rewrite
_format_commit(tree_hash, parents, author, message) -> str:
tree <tree-hash>
parent <parent-hash> <- one line per parent, zero for a root commit
author <name> <email> <unix-timestamp>
committer <name> <email> <unix-timestamp>
<- blank line
<message>
- timestamp
int(time.time()); author arrives pre-formatted as "Daniel <daniel@example.com>"
- exact spelling and order matter - this text gets hashed, any drift changes the hash
create_commit -> self.store.write_object(body.encode(), "commit")
- never touches file contents - a commit points at one tree plus its parents
create_branch -> self._refs[name] = commit_hash # Week 2 - write the real ref file
- copies a 40-char string, never object data -> that's why branching is cheap
list_branches -> return sorted(self._refs)
switch_branch -> unknown name raises RefNotFoundError; set self._head
# Week 4 - resolve ref -> commit -> tree, then self.tree.checkout(tree_hash)
merge -> return None # Week 4 fast-forward / Week 5 three-way, two parents
- CLI:
minigit commit -m "<msg>", minigit branch [<name>], minigit checkout <name>
- Wire into
minigit/cli.py - one import + one line; expect a small conflict
- Tests
tests/test_commits.py with FakeObjectStore + FakeWorkingTree at the top
- cover: body contains tree line / author line / blank line / message, root commit has zero parent lines, merge commit has two in order, branch create+list,
switch_branch("nope") raises
- quality-check green -> commit, push, PR
Team checkpoint (all four, end of week)
- contract signatures confirmed in the group chat before anyone merges
- everyone imports everyone else's class and calls one method -> shaped fake result back
- @Shuhan6017 walks your commit graph and reads your refs -> keep those names exact
Done when
Owner: @DanisLol
Module: 3 - Commits & branching
File you own:
minigit/commits.pyWeek: 1 of 10 - Contract & Skeletons
What "skeleton week" means
Interface contract - exact signatures, do not change alone
.minigit/refs/heads/<branch>"ref: refs/heads/main"(symbolic) or a raw hash (detached)Steps
cd mini-git,scripts/init.sh, skimREADME.md+minigit/errors.pyweek1/m3-commit-manager-skeleton__init__(self, repo_path=".", store=None, tree=None)->self.root,store or ObjectStore(...),tree or WorkingTree(...),self._refs: dict[str, str] = {},self._head = "main"store=/tree=arguments are the important part: fakes now, real modules later, no rewrite_format_commit(tree_hash, parents, author, message) -> str:int(time.time()); author arrives pre-formatted as"Daniel <daniel@example.com>"create_commit->self.store.write_object(body.encode(), "commit")create_branch->self._refs[name] = commit_hash# Week 2 - write the real ref filelist_branches->return sorted(self._refs)switch_branch-> unknown name raisesRefNotFoundError; setself._head# Week 4 - resolve ref -> commit -> tree, then self.tree.checkout(tree_hash)merge->return None# Week 4 fast-forward / Week 5 three-way, two parentsminigit commit -m "<msg>",minigit branch [<name>],minigit checkout <name>minigit/cli.py- one import + one line; expect a small conflicttests/test_commits.pywithFakeObjectStore+FakeWorkingTreeat the topswitch_branch("nope")raisesTeam checkpoint (all four, end of week)
Done when
storeandtreeinjectable via__init__