What is a commit?

A snapshot of the whole project, the commit before it, and the staging area that decides what goes in.

A commit is a snapshot of every file in the project, taken at one moment and kept. It records who took it and when, a message saying why, and which commit came before it. That last part is what makes a history: each commit points back at its parent, so from the newest one Git can walk back to the first.

Every commit has a name, its hash: forty hexadecimal characters, usually shown as the first seven. The name is computed from the contents, so the same snapshot always has the same name and a changed one always has a different one. The diagrams on these pages use letters instead, because letters can be read.

  1. A repository with one commit, A. The branch main points at it, and HEAD, which is where you are, points at main.

  2. You edit two files. They are changes in the working copy, and nothing about them is recorded yet.

  3. You stage one of them. The staging area is the draft of the next commit: what is staged goes in, what is not waits.

  4. Commit. B holds the staged change and points back at A, and main moves to B. README.md is still an unstaged change, untouched.

  5. Stage the rest and commit again. C points at B and B at A: the history is the chain of parents, read backwards from the newest.

Three places a change can be

The diagram holds three kinds of thing, and Git keeps them apart on purpose.

  • The working copy is the files on your disk. Editing a file changes the working copy and nothing else.
  • The staging area is the list of changes the next commit will contain. You put changes there deliberately — a file, a hunk or a single line at a time — which is how a morning’s work becomes three commits that each do one thing rather than one commit that does all three.
  • The history is the commits. Once made, a commit does not change; what looks like editing one is making a new one.

Innesta’s history lists commits newest first, the way git log does. The diagrams on these pages run the other way, oldest at the top, so that each step adds to the bottom.

On the command line

git add Scanner.swift                  # stage one file
git commit -m "Tokenise the scanner"   # make the commit
git log --oneline                      # the history, newest first

Git’s own reference: git-add and git-commit. The Pro Git book opens with the snapshot idea.

In Innesta

The working copy is the list of changes, and staging is how you choose what goes in, down to a hunk or a line. The message and the button are on committing; what you have made is in the history, with the parent links drawn as the commit graph.

The Playground is a repository made for trying this on.