Stage 2 · Tools
Git Fundamentals
init, add, commit
Create a repo, stage changes with the index, and write good commit messages.
git init
git init creates a .git/ directory in your project root. This directory contains all the metadata Git needs: the object database, HEAD pointer, branch refs, and configuration. You only run git init once per project.
mkdir webapp && cd webapp
git init
ls -la .git/The .git/ directory is the entire repository. If you delete it, you lose all history. The objects/, refs/, and HEAD file are the essential pieces — everything else is derived.
git init --bare my-project.git
ls my-project.git/A bare repository has no working tree — it only contains the .git contents directly. Bare repos are used on servers where no one edits files directly.
git add and the Index
The index (also called the staging area) is an intermediate snapshot of your working tree. When you run git add, Git reads the file content, computes a SHA-1 hash, stores the blob in .git/objects, and updates the index to point to that blob.
echo "console.log('hello')" > app.js
git add app.js
git ls-files --stageThe --stage flag shows what the index contains. You will see the file mode, blob hash, and path. This is what Git will record in the next commit.
git add README.md app.js config.json
# Or stage everything in the current directory
git add .
# Or stage all tracked (modified + deleted) files
git add -ugit add . stages everything in the current directory (including untracked files). git add -u stages all changes to already-tracked files — it does not add new untracked files.
Avoid git add . when you have unrelated changes in your working tree. Stage specific files to keep each commit focused on a single logical change. This makes git log and git bisect far more useful later.
git commit
git commit takes the current state of the index, creates a new commit object with the current timestamp, the author's identity, a pointer to the parent commit(s), and the tree snapshot. It then updates the current branch pointer to this new commit.
git commit -m "add login page and session middleware"The -m flag passes the message directly on the command line. For longer messages, omit -m and Git opens your editor. The message is stored permanently in the commit object.
git commit -am "fix null pointer in user handler"The -a flag automatically stages all modified and deleted tracked files before committing. It does not add new untracked files. Use this only for small, obvious fixes.
Writing Good Commit Messages
A commit message is documentation for the future. A good message answers three questions: what changed, why it changed, and how it works. The subject line should be imperative mood, under 50 characters, with no period.
| Bad | Good | Why |
|---|---|---|
| fixed stuff | Fix race condition in worker pool | Specific and descriptive |
| update | Bump API timeout from 5s to 30s | States the exact change |
| wip | Add CSV export for monthly reports | Complete thought, not a draft marker |
| PR feedback | Move auth middleware before route matching | Explains what the review required |
git commit -m "Add rate limiting to /api/login endpoint
- Use sliding window algorithm with Redis backend
- Return 429 with Retry-After header when limit exceeded
- Default limit: 10 requests per minute per IP
Closes #234"The subject line is the first line (imperative mood, under 50 chars). A blank line separates the subject from the body. The body explains the what and why. Footer lines reference issues or PRs.
Set git config --global commit.template ~/.gitmessage to load a template every time you commit. A common template includes sections for Type, Scope, Subject, Body, and Footer — the Conventional Commits format.
git status
git status is the most common diagnostic command. It shows which branch you are on, the state of the working tree, staged changes, and untracked files.
git status
# On branch main
# Changes to be committed:
# new file: app.js
#
# Changes not staged for commit:
# modified: README.md
#
# Untracked files:
# config.jsonThree sections: staged changes (green), unstaged changes (red), and untracked files (red). Staged changes go into the next commit. Unstaged changes must be staged first. Untracked files are new files Git does not yet know about.
Partial Staging with git add -p
Sometimes a file contains multiple unrelated changes. git add -p (patch mode) lets you stage individual hunks — groups of adjacent changed lines — so you can split one file's changes across multiple commits.
git add -p app.js
# Git shows each hunk and asks:
# Stage this hunk [y,n,q,a,d,s,e,?]?
#
# y — stage this hunk
# n — skip this hunk
# s — split into smaller hunks
# e — manually edit the hunkEach hunk is a self-contained chunk of changes. Reviewing them one by one forces you to think about whether each change belongs in this commit. This discipline produces cleaner history.
The staging area is what lets you craft precise commits. It decouples editing from committing. You can work on five files, stage only three, commit, then stage and commit the other two with a different message. No other VCS makes this as clean.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.