1The loop itself
Every day with git, on almost any project, is some version of the same five steps. You change a file. You check what changed. You tell git which of those changes to include in the next snapshot. You make the snapshot, with a message. You send it to GitHub.
| Step | Command | What it does |
|---|---|---|
| 1. Look | git status | Lists what has changed since the last commit, and whether each change is staged yet. |
| 2. Stage | git add <file> | Marks a specific change as ready to go into the next commit. |
| 3. Snapshot | git commit -m "message" | Records everything staged as one commit, with that message attached. |
| 4. Catch up | git pull | Brings in any commits that exist on GitHub but not yet on your laptop. |
| 5. Send | git push | Sends your new commits to GitHub. |
Steps 1 through 3 can happen as many times as you like before you ever touch GitHub. A real working session might run status, add and commit five separate times, once per small change, before a single push sends all five commits up at once.
2Three states, one file
At any moment, a file git is tracking sits in one of three states, and git status
exists to tell you which. The states explain why step 2 exists at all: staging is where you choose,
file by file and even line by line, what the next commit is actually going to contain.
Modified
The file on disk differs from the last commit, and git knows it, but nothing about the change has been marked for the next snapshot yet.
Staged
The change has been added with git add and will be included the next time you run
git commit. Staging is a holding area, not a commit; you can still unstage it.
Committed
The change is sealed into a snapshot in the project's history, exactly as section 2 of session 01 described a commit.
Without it, every file you had merely touched would land in the next commit whether you meant it to or not. Staging lets you edit three files, decide only one of them is actually ready, and commit that one alone, leaving the other two modified and waiting for their own commit later.
3A commit message somebody can use later
Session 01 showed this repository's real history. Two of those five messages, "Create .gitignore" and "Library view on mobile", say in a few words exactly what changed and let a future reader decide whether that commit matters to them without opening it. A message like "fix stuff" or "updates" forces that same reader to open the commit and work it out by hand, every single time, forever.
A good commit message answers one question: what changed, said plainly enough that someone with no memory of today could read it in the log and know whether to look closer. It does not need to be long. It needs to be specific.
| Weak | Specific |
|---|---|
| fix bug | Fix dark mode logo not swapping on the homepage |
| updates | Add CISSP session 14 glossary and sources |
| changes | Rename Admin & Accounting session 2 handout to match the new filename scheme |
This repository has two people editing it at once this week. One commit on the morning of
2026-10-03, meant to cover a visual change to the Library button, ended up including unrelated
homepage changes another person had made earlier and not yet committed, because both were edited in
the same shared working tree with nothing to keep them apart. The commit message described only the
Library button, so anyone reading the log later would not know the homepage changed too without
opening the commit. Nobody did anything wrong; this is simply what happens without the tool session 04
covers. A quick git status and git diff before committing is the one habit
that would have caught it, by showing every file about to be included before the commit is made.
4Pull before you push
Push sends your commits to GitHub. It only works cleanly if GitHub's copy of the branch has not
moved ahead of yours since you last checked. If someone else pushed a commit you do not have yet, git
refuses your push rather than guess how to combine the two histories, and reports something like
Updates were rejected because the remote contains work that you do not have locally. That
is not an error in what you did. It is git telling you the two histories have diverged
and asking you to pull first.
Running git pull brings those other commits onto your laptop and tries to fit yours in
after them. Most of the time this finishes with no fuss at all. Session 05 covers the case where it
cannot combine them cleanly, which is called a conflict and is far less alarming than it sounds.
5Try it: your first real commit
Do this in the practice folder you created in session 01, not in HN - Training.
- Create a plain text file, for example
notes.txt, and write one true sentence in it. Rungit status. Git reports the file as untracked, which is the state of a file git has never seen before. - Run
git add notes.txt, thengit statusagain. The same file now shows as a change staged for commit. - Run
git commit -m "Add notes file", thengit log --oneline. Your commit is now the top of the history, with its own hash. - Add a second sentence to
notes.txt. Rungit status, thengit diff. Diff shows the exact line you added, before it is staged or committed. This is the check mentioned in the aside above, the one that would have caught today's example. - Stage and commit that second change with its own message. Run
git log --onelineonce more and confirm you now have two commits of your own, on top of nothing, since this is a brand new repository.
6Check for understanding
-
Answer
Only staged changes become part of a commit. An edited file that was never staged stays in the modified state, untouched by the commit, and can be staged and committed later on its own.
-
Answer
The complaint is specificity, not length. "fix stuff" names no actual change, so anyone reading the history later, including the author, has to reopen the commit just to learn what it did. A short, specific message like "Create .gitignore" avoids that entirely.
-
Answer
Git refuses the push outright and reports that the remote contains work you do not have. It will not guess how to combine the two histories on your behalf; running git pull first is what brings the missing commits in so your push can proceed.
-
Answer
Both people were editing the same working tree with no branch keeping their work apart, so when one of them committed, git had no way to separate "my change" from "whatever else happens to be sitting here right now." A git status and git diff before committing would have shown both sets of changes staged together. Session 04 covers the tool, branches, that prevents this by design.
-
Answer
git diff shows the exact lines that changed in the working tree compared with the last commit, before anything is staged. Running it as a habit before git add is the single check that would have caught today's bundled-commit example, since it shows every pending change before it gets locked into the next commit.
7Before session 04
- Keep your practice folder and its two commits; session 04 branches directly off this history.
- Next time you see a line like "nothing to commit, working tree clean", notice it. It means every change you have made is already committed, which session 04 relies on before switching branches.
8Glossary
- Untracked
- A file git has never recorded in any commit.
- Modified
- A tracked file whose contents differ from the last commit.
- Staged
- A change marked with git add, ready to be included in the next commit.
- Staging area
- The holding area between a modified file and a committed one, where you choose exactly what the next commit will contain.
- Diverged
- The state where the remote and your local branch each have commits the other does not.
- Fast-forward
- The simple case where your branch can move straight up to match the remote with nothing to combine, because no one else's commits conflict with yours.
9Sources
- Scott Chacon and Ben Straub, Pro Git, 2nd edition, chapter 2, "Recording Changes to the Repository."
- Chris Beams, How to Write a Git Commit Message, for the seven rules behind a message worth reading later.
- The commit example in section 3 is this repository's own history, da57a3f, 2026-10-03.