The core Git loop is simple: make changes, stage what you want to include, commit the snapshot, repeat. This lesson covers each step and the inspection commands that help you understand your repository at any point.
Tracking Files
Git divides files in your working tree into three states:
| State | Meaning |
|---|---|
| Untracked | New file Git has never seen. Not included in any commit yet. |
| Tracked, unmodified | File is in the last commit and has not changed since. |
| Tracked, modified | File is tracked but has changes not yet staged. |
| Staged | Changes added to the index, ready to be included in the next commit. |
git status
git status
Run this constantly. It tells you exactly what state your files are in and suggests the next command to run. Example output:
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: src/app.ts
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
modified: README.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
config/local.yaml
git add — Staging Changes
# Stage a specific file
git add src/app.ts
# Stage all changes in the current directory
git add .
# Interactively choose which hunks (parts of files) to stage
git add -p
The -p (patch) flag is powerful: it shows you each change in each file and asks whether to stage it. This lets you craft a commit containing only logically related changes even if multiple unrelated edits are in the same file.
git commit
# Opens your configured editor for the commit message
git commit
# Write the message inline (for short messages)
git commit -m "Add user authentication endpoint"
# Stage all tracked modified files and commit in one step
git commit -am "Fix null pointer exception in login handler"
Note: -a only stages modified tracked files — it does not add new untracked files.
Writing Good Commit Messages
Commit messages are the narrative of your project. Future you — and your teammates — will read them when debugging or reviewing history. Follow the conventional Git commit message rules:
- Subject line: 50 characters or fewer, imperative mood ("Add feature" not "Added feature"), no period at the end.
- Blank line separating subject from body.
- Body: Wrap at 72 characters. Explain what changed and why — not how (the code shows how).
Add rate limiting to the authentication API
The login endpoint was being hit by credential stuffing attacks.
Rate limiting by IP (10 requests/minute) reduces this attack surface
without impacting legitimate users.
Closes #142
Inspecting History
# Full commit log
git log
# Compact one-line per commit
git log --oneline
# Visual branch graph
git log --oneline --graph --all
# Show commits by a specific author
git log --author="Ada"
# Show changes introduced by each commit
git log -p
# Show the last 5 commits
git log -5
git diff — Inspecting Changes
# Changes in working tree not yet staged
git diff
# Changes that are staged (will go into the next commit)
git diff --staged
# Difference between two commits
git diff abc1234 def5678
# Difference between two branches
git diff main feature/login
Undoing Changes
# Discard working tree changes for a file (destructive — cannot undo)
git restore README.md
# Unstage a file (keep the changes in working tree)
git restore --staged src/app.ts
# Amend the most recent commit (message or staged content)
# Only do this BEFORE pushing — rewrites history
git commit --amend