Making it permanent
The commit is what every previous step exists for. It is the durable save point that undo in unit 4, branches in unit 5, and teamwork in unit 7 all operate on. Until you commit, Git is watching but nothing is actually protected.
One-time setup comes first. Every commit records an author, so before your first ever commit Git asks you to introduce yourself. This is once per computer rather than once per project.
$ git config --global user.name "Ada Lovelace" $ git config --global user.email "ada@example.com"
Now the main event. git commit -m "message" takes everything in the staging area and saves it as a permanent snapshot.
$ git commit -m "Add pancake recipe" [main (root-commit) a1b2c3d] Add pancake recipe 1 file changed, 4 insertions(+) create mode 100644 pancakes.txt
Every part of that output means something. The commit landed on main, the default branch git status has been reporting since lesson 2-1. The words root-commit mark it as the very first commit in the repository, the one with no parent. Its short hash is a1b2c3d, computed the way lesson 1-2 described. The summary line counts one file and four added lines.
The -m flag attaches the message inline. Leave it out and Git opens a text editor and waits, because a commit without a message is not something it will create.
The loop you'll run forever
Daily Git is a three-beat rhythm:
- Edit files in the working directory.
- Stage the changes you want to keep:
git add. - Commit with a message:
git commit -m "...".
Then repeat, dozens of times a day. Two habits that make future-you grateful:
- Commit small and often. One logical change per commit ("Fix login typo", not "3 weeks of work").
- Commit working states. Each snapshot should be a save point worth returning to.
After a commit, git status reports nothing to commit, working tree clean. Clean means all three zones match: your files, the staging area, and the newest snapshot are identical.
The everyday shortcut: commit -a
Once the edit, add, commit rhythm is second nature, typing git add for every routine edit gets tedious. git commit -a -m "...", usually shortened to -am, tells Git to automatically stage every modification to files it already tracks and then commit, in one step.
The fine print is the part worth memorizing. The -a flag only re-stages files that appear in an earlier commit, so brand-new files stay untracked and are not included. Git refuses to guess whether a file it has never seen belongs in history, which is the same caution that made new files untracked back in lesson 2-1.
The practical consequence is a mixed habit. Engineers reach for -am dozens of times a day when editing files that already exist, and fall back to the explicit git add followed by git commit whenever a new file is involved or only part of the day's work belongs in the commit.
The failure mode to watch for is quiet. A commit made with -am after creating a new file succeeds, reports a sensible-looking summary, and simply leaves the new file out, so the message ends up describing work the snapshot does not contain.
A recorded session
This session makes a first commit. pancakes.txt is staged and waiting from lesson 2-2.
Each step below shows the command and the output it printed.
Step 1. Commit the staged file with the message: Add pancake recipe
~/recipe-book $ git commit -m "Add pancake recipe" [main (root-commit) a1b2c3d] Add pancake recipe 1 file changed, 4 insertions(+) create mode 100644 pancakes.txt
The same thing can be written as git commit -m 'Add pancake recipe'.
Step 2. Confirm all three zones now match.
~/recipe-book $ git status On branch main nothing to commit, working tree clean
That commit contains only the a.txt change, because a commit saves exactly what was staged.
Think of commit as photographing the staging area. a.txt had been staged by the explicit git add, so its change is now permanent. The b.txt edit was never staged, so it was not in the photograph.
Nothing about b.txt was harmed. Its change still sits in the working directory, and git status will keep reporting it as unstaged until it gets its own add and commit. That is the intended behavior rather than an oversight, since it lets one afternoon of mixed work become several honest commits.
The flag that attaches a commit message inline is -m, as in git commit -m "Add waffle recipe".
The letter stands for message, and the text follows in quotes. Quoting matters, since without it the shell would split the message into separate arguments at each space.
Leaving -m out is not an error. Git opens the text editor configured for it and waits for a message to be typed and saved, which is the route people take when writing a longer multi-paragraph explanation. Abandoning that editor without saving cancels the commit entirely.
The command that moves changes from the staging area into the repository is git commit.
Laid against the three zones from lesson 2-2, each command owns one transition. git add copies working-directory changes into the staging area, and git commit turns whatever is staged into a permanent snapshot in the .git database.
The other two commands from this unit move nothing at all. git status only reports what each zone currently holds, and git init creates the repository in the first place so that there is somewhere for commits to go.
That commit contains only the soup.txt change, and the brand-new notes.txt stays untracked.
The -a flag auto-stages modifications to files Git already tracks, and soup.txt qualifies because it appeared in an earlier commit. notes.txt has never been committed, so Git has no previous version of it to compare against and will not assume it belongs in history.
This is the trap that makes -am worth understanding rather than just using. The commit succeeds, the message says "Update", and the new file is silently absent, so the mistake usually surfaces much later when someone else clones the project and finds a file missing. Running git status after the commit would have shown notes.txt still sitting under untracked files.