1. What Git Is & Installing It
Git is a distributed version control system: it takes snapshots of a project's files over time, and every clone of a repository carries the entire history, not just the latest version. That's the key difference from older centralized systems — you can commit, branch and view history completely offline, and there's no single point of failure holding the only copy of the project.
# macOS (Homebrew)
brew install git
# Ubuntu/Debian
sudo apt install git
# Windows -- install via https://git-scm.com/download/win
# (this also installs Git Bash, a Unix-style shell for Windows)
git --version
# git version 2.4x.x
A repository ("repo") is a project folder Git is tracking — it
stores its entire history inside a hidden .git subfolder. Nothing
about a repo requires the internet or a hosting service: Git itself is just the
tool that runs on your machine. GitHub, which this course gets to in Week 3, is
a separate product that hosts repos and adds collaboration features on top.
2. Configuring Git & Your First Repo
Before your first commit, tell Git who you are — every commit is permanently stamped with this identity:
git config --global user.name "Ada Lovelace"
git config --global user.email "ada@example.com"
git config --global init.defaultBranch main
git config --global core.editor "code --wait" # optional: use VS Code for commit messages
# Confirm it stuck:
git config --list
--global applies the setting to every repo on your machine, stored in ~/.gitconfig. Drop it to set a value for just the current repo instead.
Now create a repo and make your first commit:
mkdir hello-git && cd hello-git
git init
# Initialized empty Git repository in .../hello-git/.git/
echo "# Hello Git" > README.md
git add README.md
git commit -m "Initial commit"
# [main (root-commit) 3f9a1c2] Initial commit
# 1 file changed, 1 insertion(+)
# create mode 100644 README.md
"Add login form", not "Added login form" or "Adds login form". This matches the convention Git itself uses for auto-generated messages (e.g. "Merge branch 'x'"), and it's what every team style guide asks for once you're collaborating.
3. The Three Trees: Working Directory, Staging Area & Commits
Every file in a Git repo can exist in up to three places at once, and almost every confusing Git moment traces back to not knowing which one you're looking at:
- Working directory — the actual files on disk, exactly as you see them in your editor.
- Staging area (the "index") — a draft of what your next commit will contain.
git addcopies changes here. - Commit history — permanent, named snapshots.
git committakes whatever's staged and seals it into history.
echo "console.log('hi');" > app.js
git status
# Untracked files: app.js
git add app.js
git status
# Changes to be committed: new file: app.js
git commit -m "Add app.js"
git status
# nothing to commit, working tree clean
git add is not "share this file" — it's "include this exact version of
this file in my next commit." Edit the file again after staging it, and you now
have two different versions of it in play: the staged one and the newer
working-directory one, until you git add again.
# Common shortcuts:
git add . # stage everything changed/new in the current folder
git add -A # stage everything changed/new/deleted, repo-wide
git add -p # interactively choose which hunks to stage
git commit -am "msg" # stage all tracked-file changes AND commit, in one step
git add -p is worth the habit
It lets you review and stage a file change by change instead of all-or-nothing — the single best tool for keeping commits small and focused on one logical change each.
4. Viewing History: log, diff & status
git log walks the commit history, newest first:
git log
# commit 3f9a1c2... (HEAD -> main)
# Author: Ada Lovelace <ada@example.com>
# Date: Mon Aug 17 10:02:11 2026
# Add app.js
git log --oneline --graph # compact, one line per commit
git log -p -- app.js # full diff for every commit touching app.js
git log --author="Ada" # filter by author
git diff shows what's changed but not yet staged; git diff --staged shows what's staged but not yet committed:
echo "console.log('bye');" >> app.js
git diff
# -console.log('hi');
# +console.log('hi');
# +console.log('bye');
git add app.js
git diff # empty -- nothing unstaged left
git diff --staged # shows the staged addition instead
git status is the command you'll run more than any other — it always
tells you exactly what's staged, what's modified, and what's untracked, in plain
language. When in doubt, run it.
5. Ignoring Files with .gitignore
Not everything belongs in version control: build output, dependency folders,
editor settings and secrets should never be committed. A .gitignore
file at the repo root tells Git which paths to leave untracked entirely:
# Dependencies
node_modules/
vendor/
# Build output
dist/
build/
*.log
# Editor / OS
.vscode/
.DS_Store
# Secrets -- never commit these
.env
*.pem
.gitignore only works on untracked files
If a file was already committed before you added it to .gitignore, Git keeps tracking it. Remove it from tracking (but keep it on disk) with git rm --cached path/to/file, then commit that removal.
6. Hands-on Exercise
Track a small project from scratch
Build the habit of small, well-described commits before anything else in this course.
Requirements:
- Run
git configto set your name and email, if you haven't already. - Create a folder, run
git init, and add a.gitignorethat excludes at least*.logandnode_modules/. - Create three files (e.g.
index.html,style.css,notes.log) and confirm withgit statusthatnotes.logis ignored, not just untracked. - Stage and commit the other two files in two separate commits, each with an imperative-mood message.
- Edit one file, use
git diffto review the change, then stage and commit it as a third commit. - Run
git log --oneline --graphand confirm you see all three commits.
If a file shows up in git status as untracked even though it matches your .gitignore pattern, double check the pattern is at the repo root and doesn't have a stray leading / or typo — .gitignore patterns are easy to get subtly wrong on the first try.
7. Knowledge Check
Four quick questions. Expand each to check your answer.
Q1
What's the difference between the working directory and the staging area?
What's the difference between the working directory and the staging area?
The working directory is the actual files on disk as you're editing them. The staging area is a separate draft of exactly what will go into your next commit — git add copies a snapshot of a file into staging, and further edits in the working directory don't affect what's staged until you git add again.
Q2
Why is Git called "distributed" version control?
Why is Git called "distributed" version control?
Every clone of a repository contains the full project history, not just the latest snapshot. That means committing, branching, and browsing history all work completely offline — there's no single central server required for those operations, unlike older centralized version control systems.
Q3
Why does git diff show nothing right after you run git add on a file?
Why does git diff show nothing right after you run git add on a file?
git diff (no flags) only compares the working directory against the staging area. Once a file is fully staged, there's no difference between those two, so it shows nothing. The staged change itself is visible with git diff --staged, which compares staging against the last commit instead.
Q4
You added a file to .gitignore, but git status still shows it as modified. Why?
You added a file to .gitignore, but git status still shows it as modified. Why?
.gitignore only stops untracked files from being picked up. If the file was already committed before it was added to .gitignore, Git keeps tracking it regardless of the pattern. Fix it with git rm --cached <file> to stop tracking it (while leaving it on disk), then commit that change.