Git Basics: Repositories, Commits & History
What a Git repository actually is, and how the stage-then-commit workflow builds a project's history.
What you'll learn
- Explain what a Git repository is and what 'git init' creates
- Describe the stage-then-commit workflow (git add, git commit)
- Read a commit history log and explain what each entry represents
- Explain what a diff shows between two versions of a file
Explanation
A Git repository is just a regular folder with one extra thing hiding inside it: a hidden .git directory that records every snapshot you have ever asked Git to save. Running git init in a folder is the moment that folder becomes a repository — nothing about your files changes, Git simply starts paying attention.
Git does not save every keystroke. It saves snapshots, and only when you tell it to, through a two-step ritual:
- Staging (
git add). You choose exactly which changed files should be part of the next snapshot. Think of the staging area as a shopping cart: you can add and remove items before checking out. - Committing (
git commit). You "check out" the cart. Git bundles everything staged into a permanent snapshot, tagged with a message, an author, and a timestamp. That snapshot gets a unique identifier called a hash (a string likea1b2c3d).
Because commits are snapshots layered on top of each other, they naturally form a history — a timeline of every checkpoint your project has passed through. The git log command prints that timeline, newest commit first, showing each commit's hash and message. It's the project's memory: you can always look back and see exactly what existed at any point in time, and why it changed (a good commit message answers "why," not just "what").
Why stage separately from committing? Because real work is messy. You might fix a bug and also start an unrelated cleanup in the same sitting. Staging lets you group only the bug fix into one commit and the cleanup into another, so the history stays readable — one logical change per commit, rather than one giant, unexplainable commit.
Diffs are how Git shows you what changed between two snapshots (or between your working files and the last commit). A diff highlights added lines and removed lines, line by line, so a reviewer — or future you — can see precisely what was touched without re-reading the entire file. git diff shows unstaged changes; once something is staged, Git can diff that too.
This platform never runs Git commands for you — the guided local lab below has you install nothing beyond Git itself and practice this exact stage-then-commit workflow for real, in your own terminal, against a small disposable folder. The mental model stays identical either way: a repository is a folder Git watches, changes get staged and committed as snapshots, and those snapshots stack up into a history you can read, diff, and trust.
Guided local lab
Initialize a Repository and Make Your First Commits
Runs on your computerCreate a real Git repository on your own machine and practice the stage-then-commit workflow against real files -- every command below runs in YOUR terminal; this platform does not execute any of them.
Required tools
- Git (2.x or newer)
- A terminal (or Git Bash on Windows) (any current version)
Setup
- Open a terminal.
- Create a dedicated, disposable practice folder: `mkdir git-basics-practice && cd git-basics-practice` — everything in this lab stays inside this one folder, so nothing outside it is ever at risk.
Project structure
git-basics-practice/ .git/ (created by git init) README.md
Starter files
README.md
TODO: create this file yourself with: echo "# Git Basics Practice" > README.md It is listed here only to show the expected final structure -- you create it for real, in your own terminal, using the commands below.
Requirements
- The folder is a real Git repository (has a .git directory, created by `git init`).
- README.md exists and was committed in an initial commit.
- A second commit adds a line to README.md.
- `git log` shows exactly two commits, newest first.
Commands to run
Turn the folder into a Git repository
git initCreate a real file with real content
echo "# Git Basics Practice" > README.mdStage the new file
git add README.mdCommit the staged change
git commit -m "Initial commit: add README"Add a second line to the file
echo "Learning Git one commit at a time." >> README.mdSee exactly what changed before staging it
git diffStage and commit the second change
git add README.md && git commit -m "Add description to README"Review the commit history
git log
Expected behavior
`git log` prints two commits, newest first, each with its own commit hash (a string like `a1b2c3d` — an example placeholder; your actual hash will differ and that's expected, only that two distinct commits exist matters), author, date, and message: 'Add description to README' above 'Initial commit: add README'. `git diff` (run before the second commit) prints a `+` line showing exactly the sentence you added; once that change is staged and committed, `git diff` prints nothing at all.
Verify it yourself
git log --onelineExpected: exactly two lines, each starting with a short commit hash followed by its message -- 'Add description to README' first (newest), then 'Initial commit: add README'
git statusExpected: prints 'nothing to commit, working tree clean' -- confirming every change was committed
cat README.mdExpected: prints both lines you added, in the order you added them
Troubleshooting
- `fatal: not a git repository` — You ran a git command outside git-basics-practice, or before `git init` succeeded -- confirm your location with `pwd` and that `git init` ran first.
- `git commit` opens a text editor instead of committing — You omitted `-m "message"` -- git commit needs either -m with a quoted message, or it opens your default editor to write one. Save and close that editor, or re-run the command with -m.
- Unsure whether a command here affects anything outside this folder — Every command in this lab only touches git-basics-practice/ and the hidden .git/ folder inside it -- nothing outside this one folder is ever read, created, or changed.
Stuck? Get a hint.
Extension challenge
Run `git log -p` (instead of plain `git log`) to see the full diff embedded in each commit's log entry -- notice it's the same information `git diff` showed you before committing, now permanently attached to the commit it belongs to.
When you've verified this locally, use the "Mark lesson complete" button below to record your progress.
Guided lab
Guided walkthrough: git init, add, commit, log, diff
Follow each step to see exactly what Git prints for the core stage-then-commit workflow -- this reads through the same commands as the guided local lab above; try them for real there when you're ready.
Step 1 of 5
git init creates a hidden .git directory and starts tracking the folder. It prints a one-line confirmation.
git initStuck? Get a hint.
Common mistakes
- Thinking `git add` uploads or shares code with anyone — it only stages changes locally for the next commit.
- Writing vague commit messages like 'stuff' or 'updates' instead of describing what changed and why.
- Confusing the working folder, the staging area, and the committed history as if they were one single place.
- Assuming Git stores only line-by-line diffs — it actually stores full snapshots, and computes diffs on demand for readability.
Knowledge check
Takeaway
A Git repository remembers your project as a series of deliberate, staged snapshots called commits — and that history is always yours to read back.
Summary
Git turns a folder into a repository with `git init`, tracks changes through a stage-then-commit workflow (`git add`, `git commit`), and lets you review that history with `git log` and inspect exact changes with `git diff`.
References
Your notes
Notes save automatically.
Finished this lesson?
Mark it complete to track your progress and schedule a future review.
AI tutor
The optional AI tutor isn't enabled in this deployment. All lessons, exercises, quizzes, and search work fully without it.