Skip to content

Week 1 - M3: CommitManager skeleton + commit format #4

Description

@aman-a-shah

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

  1. Setup (once): clone, cd mini-git, scripts/init.sh, skim README.md + minigit/errors.py
  2. Branch week1/m3-commit-manager-skeleton
  3. __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
  4. _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
  1. create_commit -> self.store.write_object(body.encode(), "commit")
    • never touches file contents - a commit points at one tree plus its parents
  2. 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
  3. list_branches -> return sorted(self._refs)
  4. switch_branch -> unknown name raises RefNotFoundError; set self._head
    • # Week 4 - resolve ref -> commit -> tree, then self.tree.checkout(tree_hash)
  5. merge -> return None # Week 4 fast-forward / Week 5 three-way, two parents
  6. CLI: minigit commit -m "<msg>", minigit branch [<name>], minigit checkout <name>
  7. Wire into minigit/cli.py - one import + one line; expect a small conflict
  8. 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
  9. 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

  • all 5 methods, exact signatures
  • commit text matches the format above, byte for byte
  • store and tree injectable via __init__
  • all 3 CLI commands run
  • tests pass with the fakes
  • quality-check green
  • PR open + reviewed

Metadata

Metadata

Assignees

Labels

module-3Commits and branchingweek-1Week 1 - contract and skeletons

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions