Core Concepts

Course 1 · Ch 2
Core Concepts — Working Directory, Staging Area, Commits
git init, git add, git commit — the three commands behind every single thing git does

Almost everything in git, no matter how advanced, is built on three commands you'll use constantly: git init, git add, and git commit. This chapter is entirely about understanding what each one actually does — not just memorising the syntax, but understanding the three-stage model underneath them, because that model is what makes the rest of git make sense.

The Three Stages

Every file in a git project exists in one of three places at any given moment. Understanding this is the single most important concept in the entire series — branching, merging, and almost every git command is really just moving files between these three areas.

📁
Working Directory
The actual files on your disk, as you see them in your editor or file explorer. Edits here aren't tracked by git until you explicitly tell it to look.
(just edit files normally)
📋
Staging Area
A holding area for changes you've decided should go into the next commit. Lets you build a commit out of exactly the changes you want, even if you've edited several unrelated files.
git add <file>
📦
Repository (History)
A permanent, named snapshot of everything in the staging area at that moment. Once committed, that snapshot exists forever in the project's history.
git commit -m "message"
Why a separate staging area at all?
It feels like an extra step at first, but it's genuinely useful: if you've fixed a bug and made unrelated formatting changes in the same session, you can stage and commit just the bug fix first, then stage and commit the formatting separately — keeping your history clean and each commit focused on one thing.

Starting a New Project — git init

git init turns an ordinary folder into a git repository. It creates a hidden .git folder inside it — that hidden folder is the entire repository: every commit, every branch, the full history. Delete .git and you've deleted the repository (the files in your working directory remain, but all history is gone — this is exactly the situation we ran into during the website→debserver reorg, where a `.git` folder went missing and broke a nested repository link).

$ mkdir my-project
$ cd my-project
$ git init
Initialized empty Git repository in /home/you/my-project/.git/
One repository per project, not nested
Running git init inside a folder that's already inside a git repository creates a nested repository — git will treat the inner folder strangely, often showing it as a single unexplained "modified" entry rather than its actual file changes. If you only ever run git init once per project, at the top level, this never comes up.

Checking Status — your most-used command

git status tells you, at any moment, which files are in the working directory only, which are staged, and which haven't changed since the last commit. You will run this command more than any other — get comfortable reading its output.

$ git status
On branch master
No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)
index.html
style.css

"Untracked" means git has noticed these files exist but isn't watching them for changes yet — they haven't been staged or committed.

Staging Changes — git add

git add moves a file's current state from the working directory into the staging area. It's a snapshot of that file right now — if you edit it again after staging, you need to run git add again to update what's staged.

$ # Stage one specific file
$ git add index.html

$ # Stage everything that's changed
$ git add .

$ git status
Changes to be committed:
new file: index.html
new file: style.css
Be deliberate with git add .
git add . stages every changed file in the current directory and below — convenient, but it can accidentally stage files you didn't mean to commit (temporary files, local config, accidentally-saved secrets). git add <specific-file> or reviewing with git status first is the safer habit, especially on a shared project. Chapter 6 covers .gitignore, which prevents this class of mistake entirely for files that should never be tracked.

Recording a Snapshot — git commit

git commit takes everything currently in the staging area and saves it permanently as a new point in the project's history, along with a message describing what changed and why.

$ git commit -m "Add initial homepage and stylesheet"
[master (root-commit) a1b2c3d] Add initial homepage and stylesheet
2 files changed, 48 insertions(+)
create mode 100644 index.html
create mode 100644 style.css

That a1b2c3d is the commit's unique ID (a SHA-1 hash) — every commit gets one, and it's how git refers to that exact snapshot anywhere else in the system (covered more in Chapter 8 when undoing commits, and Chapter 3 when viewing history).

Writing a good commit message

  • Summarise what changed, in the imperative mood: "Add login form" not "Added login form" or "Adding login form" — this matches git's own generated messages (merge commits, reverts) and reads cleanly in history.
  • Keep the first line under ~50 characters where practical — many tools (including GitHub's interface) truncate longer summaries.
  • One logical change per commit. "Fix login bug and update homepage copy" should usually be two commits, not one — it keeps history searchable and makes problems easier to isolate later.
  • For more detail, omit -m entirely — running plain git commit opens your configured editor, where you can write a short summary line, a blank line, then a longer explanation.

Command Reference So Far

CommandWhat it does
git initTurns the current folder into a new git repository
git statusShows what's changed, staged, or untracked right now
git add <file>Moves a file's current state into the staging area
git add .Stages all changed files in the current directory and below
git commit -m "msg"Permanently records everything staged as a new snapshot
A repository with zero commits is perfectly normal
After git init, you'll see "No commits yet" in git status — that's expected, not an error. The repository exists and is tracking the folder; it simply has no history yet until your first commit.

Chapter 2 Quick Reference

  • Three stages: Working Directory → Staging Area → Repository (History)
  • git init — creates the hidden .git folder; run once, at the project's top level
  • git status — your most-used command; shows untracked, staged, and unstaged changes
  • git add <file> — stage a specific file; git add . — stage everything (use deliberately)
  • git commit -m "message" — permanently records the staged snapshot
  • Commit messages: imperative mood, under ~50 chars first line, one logical change per commit
  • Next chapter: viewing your history — log, diff, status, and show in depth