Theory

Updated

October 30, 2026

Theory: A Commit is Immutable; Messages are for Humans and Machines

Once written, a commit object is byte-for-byte fixed. --amend and rebase do not edit it; they write a new object and slide a name. That is why hashes change and why shared history is a social problem.

Invariants

  1. Commit hash = hash of (tree, parents, author, committer, message). Change any field → new hash.
  2. Author and committer can differ (rebase, cherry-pick).
  3. Conventional Commits are a convention, not a Git feature. Hooks and forges can enforce them.
  4. Unstaging moves a path from index toward HEAD; it does not delete working-tree bytes.
  amend

  A ← B ← C     main     C has message "stuff"
  A ← B ← C'    main     C' new object; C remains in reflog

Why messages matter

git log --grep '^fix' only works if subjects are structured. Changelog generators and feat!: breaking-change scanners parse the same text. The object store does not care; your future self and CI do.

What can break

  • Amending a commit already on origin/main.
  • Empty subject or WIP on a branch you intended to merge.
  • Trailers with the wrong spelling (Co-authored-by is magic for some forges).

How to read this chapter

Anatomy, Conventional Commits, amend, unstage, lab; then templates, split/empty, trailers/mailmap, git show.