1. Courses
  2. Developer Foundations
  3. Git from the Inside
  4. Stop 1

35 minBeginner

What Git really is: snapshots and the three areas

Most Git confusion comes from one wrong picture: that Git stores a list of edits. It stores snapshots, and every command moves files between three places on your laptop. Once you see those three places, git status becomes a dashboard you can read at a glance, and the rest of Git starts to make sense.

By the end you can

  • Explain what version control does for a team, and why Git stores snapshots instead of edits
  • Say what a commit contains, and why its ID changes if anything in it changes
  • Move changes between the working folder, the staging area and the repository with add, commit and restore
  • Read every line of git status, in both long and short form
  • Set up Git, make three commits, look inside one to prove it is a snapshot, and model the staging area in code

The everyday picture

Imagine a store manager who keeps a photo album of the shop floor. Before each photo, staff arrange the shelves: move the festival gift boxes to the front, refill the cooking oil, fix a crooked price card. That is the shop floor as it is right now, messy and changing.

Then the manager decides what goes into the next photo. Aisle 3 is ready; aisle 5 is still half done, so she frames the photo to leave it out. That framing is a separate step from the arranging. Finally she takes the photo, writes the date and a caption on the back, "Festival display, aisle 3", and puts it in the album.

Old photos never change. If someone moves the gift boxes tomorrow, last week's photo still shows them where they were. To see what changed between two days, you lay two photos side by side. Git works exactly like this: the working folder is the shop floor, the staging area is the framing, and a commit is the photo in the album.

What version control is for

This is the first lesson of Git from the Inside, and it assumes no Git experience at all. You need Git installed, a terminal and an editor such as VS Code; the Your Developer Setup course walks through all three if you have not set them up yet.

Before Git, teams shared code as zip files and folders called final, final-v2 and final-v2-fixed. Nobody could say which version was on the store handhelds, who changed the discount logic, or how to get last Tuesday's working copy back. answers those questions. It gives you four things:

  • History: every saved version, with who made it, when, and a message saying why.
  • Undo: return any file, or the whole project, to any earlier version.
  • Parallel work: several people change the same project at once and combine their work later (Branches and merging).
  • Proof: an exact record of what shipped, which is how you answer "when did this behaviour change?" (Reading code like a detective).

is the version control tool almost every team uses today. It runs entirely on your laptop. The whole history lives in a hidden folder called .git inside your project. No server, no account and no internet are needed for anything in this lesson. Sharing through GitHub comes later, in GitHub: remotes, clone, push and pull.

Snapshots, not edits

Many people imagine Git as a list of edits: "line 4 changed, then line 9 was added". It is not. Each time you save a version, Git records a : what every tracked file looked like at that moment. When you ask "what changed?", Git compares two snapshots and computes the difference on the spot.

Storing every file every time sounds wasteful, so Git uses a trick. It names each file's content by a fingerprint of that content (a hash, explained below). If a file did not change, its fingerprint is the same, so the new snapshot points to the copy Git already has. A commit that changes one file in a project of 2,000 files stores one new file and reuses the other 1,999. Later, Git also compresses similar contents together on disk (Inside the .git folder). You get the simple model, full pictures, at the cost of small changes.

This is why Git is fast at things that feel heavy: switching to last month's version means reading one snapshot, not replaying a month of edits.

Quick check

You ask Git to show the project as it was 200 commits ago. What does it do?

What a commit is

A is one photo in the album. It holds:

  • a pointer to the snapshot of all files (Git calls it a tree),
  • the author and committer, each with a name, email and timestamp,
  • the message: one line saying what and why, optionally followed by more detail,
  • a pointer to its parent: the commit that came just before it. The very first commit has none.

Git feeds all of that into a hash function, SHA-1 by default, and gets a 40-character such as e5b14539196777869d5c87ddc86561e127094891. You normally see the first 7 characters, e5b1453, which are enough to identify it in a project. The ID is a fingerprint of the content, so change anything, even one letter of the message, and you get a different ID. That is why old commits never change: "editing" a commit really creates a new commit with a new ID (Rewriting history safely). Git plans to move new repositories to the stronger SHA-256 hash in Git 3.0; the idea stays the same.

Because every commit points to its parent, the commits form a chain going back in time. Your project's history is that chain, read from the newest commit backwards.

Quick check

Which of these is not part of what a commit's ID is calculated from?

commits snapshot of every file e5b1453 main docs: show usage README.md 65866ea index.js e5a5bd6 prices.json 27f31c0 parent 3624f79 feat: prices.json README.md 6ecc521 index.js e5a5bd6 prices.json 27f31c0 parent 9f18d2a feat: one price README.md 6ecc521 index.js 96680e7 first commit: no parent new content same content, reused
The three commits from the Build it section, newest at the top. Each commit points to its parent and to a full snapshot. The short codes on the right are the stored contents of each file: index.js did not change in the newest commit, so both snapshots point to the same stored content e5a5bd6.

The three areas

Your project lives in three places at once, and almost every Git command moves changes between them.

The (Git's docs say working tree) is the shop floor: the files you see in VS Code and edit. The , also called the index, is the framing: the exact content of every file that will go into the next commit. The , the .git folder, is the album: every commit ever made.

git add index.js copies the current content of index.js into the staging area. It does not mark the file for later; it takes a copy now. git commit turns the whole staging area into a new snapshot and adds it to the repository. Two commands go the other way. git restore --staged index.js puts the last commit's version back into the staging area, which "unstages" your change; your edits in the working folder stay. git restore index.js copies the staged version over your working file, which throws away your unstaged edits with no undo. Older tutorials use git reset HEAD index.js and git checkout -- index.js for these two; git restore replaced them in Git 2.23 because one command name was doing too many jobs.

Why have a middle step at all? Because real work is messy. While fixing a bug you also add a debug line, rename a variable and start a second idea. The staging area lets you choose: put only the fix in this commit, and the rest in another commit, or in none. Small, focused commits are much easier to review, understand and undo (Everyday Git).

Quick check

You edit index.js, run git add index.js, then run git restore --staged index.js. Where is your edit now?

Working folder the files you edit git add copy in git restore discards edits status: not staged Staging area the next commit (index) git commit snapshot git restore --staged status: to be committed Repository .git: all commits
The three areas. git add copies a file's current content into the staging area; git commit saves the staging area as a new snapshot. Going back, git restore --staged unstages by copying the last commit's version into staging, and git restore overwrites your working file with the staged version. git status reports the differences between neighbouring areas.
Think first: you run git add index.js, then edit index.js again, then git commit. Which version is in the commit?

The version from the moment you ran git add. The commit is made from the staging area, and add copied the file then. Your later edit is still in the working folder, and git status shows index.js under "Changes not staged for commit". Short status shows MM: modified in staging, and modified again in the working folder. Run git add again to include the newer edit. Build it step 6 shows exactly this.

git status is your dashboard

Run git status before and after every Git command until you no longer need to. It compares the three areas and puts every changed file into one of three groups:

  • Changes to be committed: the staging area differs from the last commit. These go into the next commit.
  • Changes not staged for commit: your working file differs from the staging area. These do not go into the next commit unless you add them.
  • Untracked files: files Git has never been told about. Git ignores them completely until you add them once. After that they are .

Status also prints a hint under each heading with the exact command to move files, such as (use "git restore --staged <file>..." to unstage). Those hints are correct and worth reading. git status -s gives the same information in two columns: the left letter is the staging area compared with the last commit, the right letter is the working folder compared with the staging area.

Short statusMeaningGoes into next commit?
??Untracked: Git does not know this fileNo
A (A, space)New file, stagedYes
M (space, M)Modified, not stagedNo
M (M, space)Modified and stagedYes
MMStaged, then modified againOnly the staged version
D / D Deleted, not staged / stagedOnly if staged

Quick check

git status -s prints M README.md (a space, then M). What happens to that change if you run git commit now?

Try the three areas in the simulator below. It starts the way a real day often does: two commits exist, index.js is edited and prices.json is a new file. Stage just one of them and commit, then edit a staged file again and watch git status list it twice. Try git restore on an edit and read the warning.

Simulator

Loading the simulator…

  • The git status output under the columns updates after every click and matches what real Git prints for that state.
  • A commit only takes what is in the staging area. Files left in the working folder stay there, still changed, for the next commit.

Build it

Set up Git, make three commits on a tiny project, and read git status and git log at each step. All outputs are from Git 2.55. Your commit IDs will differ, because they include your name and the time. When you are done, the Practice section has a small model of the staging area to write and test in your browser.

  1. Tell Git who you are, once per laptop

    Every commit records a name and email, and Git refuses to commit without them. Use the email you will use on GitHub, so your commits link to your account later. --global saves the settings in ~/.gitconfig for every repository on this laptop. The other two lines name the first branch main and make VS Code the editor for longer commit messages.

    Terminal
    git config --global user.name "Your Name"
    git config --global user.email "you@example.com"
    git config --global init.defaultBranch main
    git config --global core.editor "code --wait"
    git config --global --list
    Output
    user.name=Your Name
    user.email=you@example.com
    init.defaultbranch=main
    core.editor=code --wait
  2. Create a repository

    git init creates the hidden .git folder. That folder is the repository; delete it and the history is gone, while your files stay. Without the init.defaultBranch setting, Git 2.55 prints a long hint and names the branch master.

    Terminal
    mkdir -p ~/work/price-check && cd ~/work/price-check
    git init
    Output
    Initialized empty Git repository in /Users/you/work/price-check/.git/
  3. Add two files and read the dashboard

    Create index.js and README.md in VS Code. Prices are stored as whole cents (integers), so $4.25 is 425; whole numbers never pick up the rounding errors that decimals like 0.1 + 0.2 do. "Article" is the data name for a product in this project.

    JavaScript
    // index.js: print the shelf price of one article
    const prices = { 'A-1001': 425, 'A-2040': 189 }; // cents
    const code = process.argv[2] ?? 'A-1001';
    console.log(`${code}: $${(prices[code] / 100).toFixed(2)}`);
    Terminal
    git status
    Output
    On branch main
    
    No commits yet
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    	README.md
    	index.js
    
    nothing added to commit but untracked files present (use "git add" to track)
  4. Stage both and make the first commit

    Use a Conventional Commit message, a type such as feat or docs, a colon and a short summary (Everyday Git).

    Terminal
    git add index.js README.md
    git status
    git commit -m "feat: print the price of one article"
    git log --oneline
    git status
    Output
    On branch main
    
    No commits yet
    
    Changes to be committed:
      (use "git rm --cached <file>..." to unstage)
    	new file:   README.md
    	new file:   index.js
    
    [main (root-commit) 9f18d2a] feat: print the price of one article
     2 files changed, 7 insertions(+)
     create mode 100644 README.md
     create mode 100644 index.js
    9f18d2a (HEAD -> main) feat: print the price of one article
    On branch main
    nothing to commit, working tree clean

    "root-commit" means it has no parent. (HEAD -> main) says you are on the branch main, which points at this commit (Branches and merging). "working tree clean" means all three areas agree: nothing is waiting anywhere.

  5. Change one file, add another

    Move the prices into their own file. Create prices.json and change index.js to load it, then run the program and check the dashboard.

    JSON
    { "A-1001": 425, "A-2040": 189, "A-0007": 150 }
    Terminal
    node index.js A-0007
    git status
    git status -s
    Output
    A-0007: $1.50
    On branch main
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
    	modified:   index.js
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    	prices.json
    
    no changes added to commit (use "git add" and/or "git commit -a")
     M index.js
    ?? prices.json
  6. Stage, then edit again

    Stage both files, then change the comment in index.js to // prices in cents, keyed by article code and save. The file now has one version staged and a newer one in the working folder.

    Terminal
    git add index.js prices.json
    git status -s
    # edit the comment in index.js and save, then:
    git status -s
    git status
    Output
    M  index.js
    A  prices.json
    MM index.js
    A  prices.json
    On branch main
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
    	modified:   index.js
    	new file:   prices.json
    
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
    	modified:   index.js

    index.js appears in both groups because the staging area and the working folder each hold a different version. The hint under the first heading also changed: before the first commit it said git rm --cached; now there is a commit to restore from, so it says git restore --staged.

  7. Move things back with restore

    Unstage prices.json, then discard the newer comment edit in index.js.

    Terminal
    git restore --staged prices.json
    git status -s
    git restore index.js
    git status -s
    Output
    MM index.js
    ?? prices.json
    M  index.js
    ?? prices.json

    Unstaging a new file makes it untracked again; the file is still on disk. git restore index.js copied the staged version over the working file, so the comment edit is gone for good and the earlier staged change remains. That is the only command in this lesson that can lose work, which is why the simulator asks before it runs it.

  8. Make two more commits

    Stage prices.json again and commit. Then add a usage line to the README and commit it with -a, which stages every changed tracked file first. It is safe here because git status would show only README.md.

    Terminal
    git add prices.json
    git commit -m "feat: load prices from prices.json"
    # add a usage line to README.md and save, then:
    git commit -am "docs: show usage in README"
    git log --oneline
    Output
    [main 3624f79] feat: load prices from prices.json
     2 files changed, 2 insertions(+), 1 deletion(-)
     create mode 100644 prices.json
    [main e5b1453] docs: show usage in README
     1 file changed, 2 insertions(+)
    e5b1453 (HEAD -> main) docs: show usage in README
    3624f79 feat: load prices from prices.json
    9f18d2a feat: print the price of one article

    git log --oneline lists commits newest first: short ID and the first line of the message.

  9. Look inside a commit

    git cat-file -p prints a stored object as Git keeps it. The newest commit is plain text: its snapshot (tree), its parent, author, committer and message. git ls-tree lists a snapshot; HEAD means the current commit and HEAD~1 its parent.

    Terminal
    git cat-file -p HEAD
    git ls-tree HEAD
    git ls-tree HEAD~1
    Output
    tree aedee8e6ea9e5feead2f8fc6ac0e164fbe5f7134
    parent 3624f79ef247ebceecff27e79a9272e5aed49d34
    author Your Name <you@example.com> 1791357076 +0600
    committer Your Name <you@example.com> 1791357076 +0600
    
    docs: show usage in README
    100644 blob 65866ea2fead7b24a97ce77840793a544832c1d7	README.md
    100644 blob e5a5bd6143675b12c300ff774dd4e6348808d861	index.js
    100644 blob 27f31c052ed4ad43f3a71618dc7631f02194434b	prices.json
    100644 blob 6ecc521332e5791bd10f72cb8c42b677699ef54b	README.md
    100644 blob e5a5bd6143675b12c300ff774dd4e6348808d861	index.js
    100644 blob 27f31c052ed4ad43f3a71618dc7631f02194434b	prices.json

    Both snapshots list all three files: they are full pictures, not changes. Only README.md has a new ID; index.js and prices.json point to the same stored content as before. The timestamp is seconds since 1970, and +0600 is the author's time zone, six hours ahead of UTC. Inside the .git folder explores these objects properly.

  10. Read an old photo

    The first commit is still there, unchanged. git show COMMIT:FILE prints a file as it was in any commit, without touching your working folder.

    Terminal
    git show HEAD~2:index.js
    Output
    // index.js: print the shelf price of one article
    const prices = { 'A-1001': 425, 'A-2040': 189 }; // cents
    const code = process.argv[2] ?? 'A-1001';
    console.log(`${code}: $${(prices[code] / 100).toFixed(2)}`);

Bring it to your team

These questions are about habits, and you can ask them without reading any code.

  • "Does each commit in this PR do one thing? Can you show me the file list with git show --stat?"
  • "Is our commit email the same as our GitHub email, so history links to real people?"
  • "Do we have a .gitignore and a .gitattributes, so new files and line endings behave the same on Windows and macOS?"
  • "If this laptop is lost tonight, which work exists only in its working folder and has never been committed and pushed?"
  • "When you say 'it's in Git', do you mean committed, or just saved in the editor?"

Red flags

  • Commit messages like "update", "fix", "wip" on every commit.
  • One giant commit per day, mixing a bug fix, a refactor and config changes.
  • Someone deleting .git to "start fresh" when Git gets confusing.
  • Commits by "root" or "user@laptop", because nobody set user.name and user.email.

Practice

Model the staging area in code

A repository is three maps from file name to file content: head (the last commit), index (the staging area) and work (the working folder). Like real Git, the index starts as a copy of the last commit. Write two functions. add(repo, file) copies the file's current content from work into index. status(repo) returns the three groups that git status prints, each sorted by name:

  • staged: files whose content in index differs from head (this includes new files),
  • notStaged: files that are in index and whose content in work differs from it,
  • untracked: files in work that are not in index.
JavaScript exerciseRuns in your browser with tests
// repo = { head: {}, index: {}, work: {} }, each mapping file name to content
function add(repo, file) {
  // copy the file's current content from the working folder into the staging area
}

function status(repo) {
  // return { staged: [...], notStaged: [...], untracked: [...] }, each sorted by name
  return { staged: [], notStaged: [], untracked: [] };
}
Ctrl + Enter runs
Show a solution
JavaScript
function add(repo, file) {
  repo.index[file] = repo.work[file]; // a copy of the content now, not a reference to the file
}

function status(repo) {
  const names = [...new Set([
    ...Object.keys(repo.head), ...Object.keys(repo.index), ...Object.keys(repo.work),
  ])].sort();
  return {
    staged: names.filter((f) => repo.index[f] !== repo.head[f]),
    notStaged: names.filter((f) => f in repo.index && repo.work[f] !== repo.index[f]),
    untracked: names.filter((f) => f in repo.work && !(f in repo.index)),
  };
}
Pass the exercise to finish this task.

Read a dashboard and plan the commit

You fixed a stock count bug in the Store app. git status -s prints the four lines below. Write down (1) exactly what git commit would save right now, and (2) the commands that give you one commit containing the fix in both source files, in their newest versions, and nothing else.

Output
M  src/stock.js
MM src/count.js
?? .env
?? notes.txt
  • You say the commit would hold src/stock.js and the staged version of src/count.js, not its newest edit
  • You run git add src/count.js again before committing
  • You never stage .env or notes.txt, and you suggest adding .env to .gitignore
  • You check with git status (or git diff --staged) before running git commit
Show a model answer

(1) Right now the commit would save src/stock.js and the version of src/count.js that was staged earlier. The newer edit to count.js (the right-hand M) would stay behind, and the two untracked files are ignored by commit.

Terminal
git add src/count.js        # stage the newest version
git status -s               # expect: M  src/stock.js, M  src/count.js, ?? .env, ?? notes.txt
git commit -m "fix: round loose items to 0.01 kg in stock count"
echo ".env" >> .gitignore    # so git add . can never pick it up

Check yourself

You change one file in a project of 500 files and commit. What does Git store for the new commit?

git status -s shows MM src/stock.js. If you run git commit now, what is committed for that file?

A teammate changes one word in the message of an old commit. Why does that commit's ID change?

Flashcards

Open my review

Key takeaways

  • Git stores snapshots of every tracked file. Unchanged content is stored once and reused, and differences are computed on demand.
  • A commit is a snapshot plus author, committer, dates, message and parent. Its ID is a hash of all of that, so commits never change.
  • Three areas: the working folder (what you edit), the staging area (the next commit) and the repository (all commits). add and commit move forward; restore --staged and restore move back.
  • git status is the dashboard: to be committed, not staged, untracked. Read it before and after every command.
  • Everything in this lesson is local, in the .git folder. Committed is not the same as backed up; that comes with pushing in GitHub: remotes, clone, push and pull.
Episode transcriptA photo album of the shop floor · about 11 minutes · tap any line to play from there
  1. NadiaImran, when you hear the word Git, what picture comes to mind?
  2. ImranA long list of edits. Line four changed, line nine added, and Git replays them all to rebuild a file.
  3. NadiaThat's the picture most people have, and it's the source of most Git confusion. Git doesn't store edits. It stores photos.
  4. ImranPhotos of what?
  5. NadiaOf the whole project, at the moment you save a version. Today we build that picture, and by the end, git status should read like a dashboard.
  6. NadiaThe lesson's picture is a photo album of the shop floor. Before each photo, staff arrange the shelves. Gift boxes to the front, refill the oil, fix a crooked price card.
  7. NadiaThen the manager frames the photo. Aisle three is ready, aisle five is half done, so she leaves it out of the frame. Then she takes the photo, writes a caption on the back, and puts it in the album.
  8. ImranAnd old photos never change.
  9. NadiaNever. If someone moves the gift boxes tomorrow, last week's photo still shows them where they were. To see what changed, you lay two photos side by side.
  10. ImranSo the shop floor is my project folder, and the photo is a commit. What's the framing?
  11. NadiaThe staging area. We'll get there. First, why bother with version control at all?
  12. ImranI remember folders called final, final two, and final two fixed.
  13. NadiaEveryone does. Version control gives you four things instead. History, with who changed what and why. Undo, back to any earlier version. Parallel work, so several people change the project at once. And proof of exactly what shipped.
  14. NadiaAnd Git does all of it on your laptop. The whole history lives in a hidden folder called dot git, inside your project. No server and no internet for anything in this lesson.
  15. ImranBack to the photos. If every commit stores every file, isn't that a huge waste of space?
  16. NadiaIt would be, except for one trick. Git names each file's content by a fingerprint of that content. If a file didn't change, its fingerprint is the same, so the new snapshot points to the copy Git already has.
  17. ImranSo in a project of two thousand files, a commit that changes one file stores one new file.
  18. NadiaAnd reuses the other one thousand nine hundred and ninety-nine. You get full pictures for the price of small changes.
  19. ImranWhat exactly is inside a commit, then?
  20. NadiaFour things. A pointer to the snapshot of all files. The author and committer, with names, emails and times. The message. And a pointer to its parent, the commit just before it.
  21. NadiaGit feeds all of that into a hash function and gets a forty character ID. You usually see the first seven characters.
  22. ImranAnd that's why old commits can't change.
  23. NadiaRight. The ID is a fingerprint of the content. Change one letter of the message, and you get a different fingerprint. So editing a commit really means making a new one.
  24. NadiaThe first diagram shows this with real commits from the lesson. If you can see it, three boxes go down the left side, each with an arrow to the one below, labelled parent. If not, picture three photos stacked, newest on top, each pointing to the one before.
  25. NadiaNext to each commit is its snapshot, a list of every file. In the newest commit, only the README is new. The other two files point to exactly the same stored content as the commit before.
  26. ImranNow the three areas.
  27. NadiaYour project lives in three places at once. The working folder is the shop floor, the files you edit in VS Code. The staging area, also called the index, is the framing: exactly what the next commit will contain. And the repository, the dot git folder, is the album.
  28. NadiaThe second diagram stacks them. If you're looking, three boxes, top to bottom: working folder, staging area, repository. If not, picture three shelves, one above the other.
  29. NadiaGoing down: git add copies a file into the staging area. Git commit turns the whole staging area into a new photo in the album.
  30. ImranAnd going up?
  31. NadiaGit restore, dash dash staged, unstages a file. It puts the last commit's version back into the staging area, and your edits stay safe in the working folder.
  32. NadiaPlain git restore, without staged, is the dangerous one. It copies the staged version over your working file, and your unsaved edits are gone. No undo.
  33. ImranSo git add marks a file, and the commit picks up whatever the file looks like at that moment.
  34. NadiaThat's the most common wrong idea, Imran. Git add doesn't mark the file for later. It takes a copy now. If you edit again after adding, the commit gets the old copy, the one you added.
  35. ImranAnd the newer edit?
  36. NadiaStill in your working folder, waiting. Git status lists the file twice, once as staged and once as not staged. In the short form it shows two letters M side by side.
  37. ImranWhy have a middle step at all? Other tools just save.
  38. NadiaBecause real work is messy. While fixing a bug, you add a debug line, rename something, and start a second idea. The staging area lets you put only the fix into this commit. Small, focused commits are much easier to review and to undo.
  39. ImranGive me the Mangrove version.
  40. NadiaA developer on the Store app fixes a stock count rounding bug. To test it, he points the API address in a config file at his own laptop, and adds some log lines.
  41. NadiaIf he commits everything, the next build for the handheld scanners tries to reach his laptop, and stock counts fail in every store that installs it. With staging, he adds only the two files with the fix, and keeps the config change local.
  42. ImranThat's a real outage avoided by one habit. Across three hundred and twenty stores.
  43. NadiaAnd the habit is: read git status before every commit. It sorts every changed file into three groups. Changes to be committed. Changes not staged. And untracked files, which Git ignores until you add them once.
  44. NadiaUnder each heading it prints a hint with the exact command to move files. Those hints are correct, and worth reading.
  45. ImranWhat about git commit dash a? My team uses it all the time.
  46. NadiaIt stages every changed file Git already tracks, then commits. It silently leaves out new files. And git add dot has the opposite risk: it stages everything, including a dot env file with passwords, unless a gitignore says otherwise.
  47. NadiaThe lesson has a simulator for all this. Later, try it: it starts with two commits, an edited index file and a new prices file. Stage only one and commit, then edit a staged file again and watch git status list it twice.
  48. NadiaThe Build-it section does the same with real Git. First you tell Git your name and email, once per laptop, because every commit records them. You also name the first branch main.
  49. NadiaThen git init creates the dot git folder. You add two files, an index file that prints an article's price, and a README, and read git status. Both are untracked.
  50. ImranThen the first commit.
  51. NadiaYou add both, commit, and git status says working tree clean. All three areas agree. Then you move the prices into a prices dot json file, stage both files, and edit the comment again. Short status shows M M.
  52. NadiaYou unstage the prices file and watch it turn back into untracked. Then you discard the comment edit with git restore, and it's gone.
  53. ImranAnd the end?
  54. NadiaTwo more commits, so you have three. Then you look inside the newest one with git cat file. It's plain text: a tree, a parent, the author, the committer and the message. The snapshot lists all three files, and only the README has new content.
  55. NadiaLast, you print the index file as it was in the first commit. It's still there, exactly as you wrote it. The old photo never changed.
  56. ImranCan I try the staging area without a terminal?
  57. NadiaTwo ways. The simulator, and the practice section. There you write a tiny model of the staging area in code, an add function and a status function, and your browser checks it with tests.
  58. ImranWhat do I bring to my team?
  59. NadiaAsk: does each commit in this pull request do one thing? Can you show me the file list for each one?
  60. ImranAnd one I like for the risk register: if this laptop is lost tonight, which work exists only in its working folder, never committed or pushed?
  61. NadiaGood. And listen for red flags: messages like update or fix on every commit, one giant commit per day, or someone deleting the dot git folder to start fresh.
  62. NadiaHere's one to think about. You change one file in a project of five hundred files, and commit. What does Git store? Take a second.
  63. ImranA snapshot listing all five hundred files. New content for the one I changed, and the other four hundred and ninety-nine reused.
  64. NadiaExactly. Not a list of changed lines, and not five hundred new copies. And it's stored the moment you commit. Pushing only copies it somewhere else.
  65. ImranLet me sum up. One: Git stores snapshots of the whole project, and unchanged files are reused, so it stays small.
  66. ImranTwo: a commit is a snapshot plus author, message and parent, and its ID is a fingerprint, so commits never change.
  67. ImranThree: three areas. Working folder, staging area, repository. Add and commit move forward. Restore moves back.
  68. NadiaOne correction on the third. Restore with dash dash staged is safe. Plain restore throws away your edits. Read git status first, every time.
  69. ImranAnd the flashcards at the end are my review for tomorrow morning.
  70. NadiaNext time, everyday Git. Reading diffs, staging half a file, writing good commit messages, and finding who changed a line.
  71. ImranSee you then.
Finished reading?Mark it complete to fill in its stop on your course line.

Use it at work

Runbook

Symptoms, first checks with commands, fixes and when to escalate, for one alert.

Open in the DevOps & TechOps Lab
Next stopEveryday Git: status, diff, log and good commits
Was this lesson helpful?
Questions and discussion

Loading the discussion…