5. Git Without the Mystery

This chapter teaches you to inspect a meaningful change and save it as a commit. Begin with a working Chapter 4 toolchain and the CP01 source bundle supplied without learner Git history. Work in a new practice folder. By the end you will have two explanatory commits and will be able to say exactly which contents each saved.

An assistant can make a useful edit quickly. The next problem is knowing what changed and deciding whether to keep it. A copied folder named final-really-final does not make that decision clear. Git records selected versions and helps you compare them. We will use a small reporting-label change so the mechanics stay visible while the program remains understandable.

1. Local Git, hosting, and synchronization

Git is version-control software. A local repository contains recorded history and metadata alongside a working copy of project files. GitHub is a hosting and collaboration service that can store a remote copy of that history. You can inspect changes and make local commits without pushing anything to GitHub. Chapter 6 adds the remote step.

Cloud file synchronization serves a different purpose. A synchronizer may copy whichever files currently exist; it does not necessarily give you a reviewed, intentional sequence of project changes. Git also does not automatically preserve every untracked file or unsaved editor buffer. It records what you deliberately include in commits. Use it with ordinary backup practices rather than treating either as a complete replacement for the other.

A repository is not a magic “correct” folder. You can commit a broken program, a misleading README, or a secret. Git will faithfully preserve that choice. Our workflow puts inspection and relevant checks before the commit, so history records decisions you can explain. An intentionally failing exercise may be committed too, provided its message and documentation identify it as a seeded fault.

2. Understand the three places

The working tree is the project content you edit. The staging area, also called the index, is the content selected for the next commit. A commit records that selected snapshot with metadata and a relationship to earlier history. Staging a file selects its contents at that moment; later edits can remain unstaged. Pro Git, recording changes

Figure D05 shows these three places and the operations between them. Saving in the editor changes the working tree. Staging selects content for the next commit. Committing records the staged snapshot. Pushing, which comes later, transfers commits to a remote. Do not call all four actions “saving,” because each answers a different question.

Saving changes the working tree; add selects contents in staging; commit records that selected snapshot. Ordinary and cached diffs compare different states.

D05. Saving changes the working tree; add selects contents in staging; commit records that selected snapshot. Ordinary and cached diffs compare different states.

Consider a README with a corrected heading. You stage it, then add a troubleshooting paragraph. The staged snapshot has the heading correction, while the working file has both edits. A commit at that point saves the staged version. This is useful when intentional and confusing when accidental. Two diff views will make the distinction visible.

3. Initialize the practice repository

Extract the CP01 source bundle into a new sensor-monitor-git folder, separate from the unchanged starter. The bundle for this exercise must not already contain a .git directory. Open it in VS Code and confirm its README and source tree. Do not run initialization in your home folder, Downloads folder, or the parent of unrelated projects.

In PowerShell, from the extracted practice root:

# Context: PowerShell in the new sensor-monitor-git source-only folder.
Get-Location
git init -b main
git status

git init -b main creates repository metadata and names the initial branch main. It does not upload files or create a commit. The expected status lists untracked project files and indicates that no commit exists yet. Exact wording varies with Git version. If Git reports an existing repository, inspect the folder before proceeding; you may have opened the wrong extraction. git init reference

Set repository-local identity before the first commit. Use your chosen author name and, if you want GitHub attribution without exposing your private address, the exact no-reply address shown in your GitHub email settings. Do not invent an account-specific address from this example:

# Context: PowerShell in this practice repository; replace both example values.
git config user.name 'Your chosen author name'
git config user.email 'YOUR-VERIFIED-NOREPLY-ADDRESS'
git config --get user.name
git config --get user.email

These are local settings because --global is omitted. Commit identity is metadata; it is not GitHub authentication. The host's email privacy settings explain how its no-reply address works. Check your actual setting before saving it. GitHub commit email

4. Decide what belongs in history

Source code, reproducible scripts, requirements, tests, and useful documentation belong in this practice repository. Generated compiler output can usually be recreated and should be excluded. The supplied .gitignore defines relevant exclusions such as the project's build directory. Read it rather than replace it with a long list copied from an unrelated stack.

A .gitignore entry prevents matching untracked files from appearing as ordinary candidates for addition. It does not remove a file already tracked in history. It also does not encrypt a credential or make an uploaded secret private. This chapter's deliberate mistake uses harmless generated output after a baseline commit; do not practice with sensitive files. gitignore reference

Run git status and inspect the list. If you see a personal document, credential file, or an entire unrelated directory, stop and correct the project boundary. If you see expected firmware, host code, scripts, and documentation, stage those named paths. The source bundle may contain additional tracked support files; use its README and release tree to account for them.

# Context: PowerShell in the CP01 practice repository.
git add README.md .gitignore dependencies.json firmware host scripts fixtures docs CHECKPOINT.md
git status
git diff --cached --stat
git diff --cached

Add any other intended source-bundle documents explicitly after reviewing them. Do not use a broad command merely to silence untracked status. In VS Code, the Source Control view shows changed files; its stage control selects them, and the Staged Changes group corresponds to the staging area. Read the diff in either interface before committing.

5. Commit the baseline

Run the documented baseline check from the practice folder. Save the result in your learner notebook outside generated build output, or in a deliberate evidence file if the exercise calls for it. Then make the baseline commit:

# Context: PowerShell in the CP01 practice repository after baseline review.
git commit -m 'Record sensor monitor baseline and build instructions'
git log --oneline -2
git status

A commit records the staged content, along with its message and metadata. A useful message explains the purpose of the change. “Update” and “AI changes” do little to help your future self choose a recovery point. A commit's identifier is computed from its contents and metadata, so your identifier will differ from a screenshot's even when the teaching steps are equivalent. git commit reference

Expected observations are one baseline entry in history and no unintended changes left in the working tree. A clean status does not mean the code is correct; it means the relevant tracked states agree and there are no listed untracked candidates. Keep the test result separate from the Git-state observation.

Figures SS05-01 and SS05-02 show initialization and the reviewed file selection. They should show the actual practice path and expected exclusions, not another repository whose contents happen to look similar. Your own outputs are valid even when line counts and commit IDs differ.

6. Worked example: read a report-label diff

Find the exact line Report label: synthetic. in the CP01 README. Change it to Report label: synthetic input. and save. This is a human-facing documentation label, not a machine-readable key or firmware edit. The exact path is README.md; the baseline's fixed host sample remains 25.00.

The expected diff for that edit is:

-Report label: synthetic.
+Report label: synthetic input.

This display is the expected comparison, not a captured command result. Inspect your actual diff to establish what changed.

The minus line is the previous content; the plus line is the new content. These markers belong to the diff display and are not characters to paste into the README. Context lines help locate the change. The file header identifies which file changed. A whole file appearing replaced can indicate formatting or line-ending changes that deserve inspection before acceptance. git diff reference

Run the two comparisons:

# Context: PowerShell in the practice repository after saving the edit.
git diff
git diff --cached

Before staging, the ordinary diff should show your edit; the cached diff should be empty if nothing is staged. Stage only README.md, then run both commands again. The selected edit should move to the cached comparison. This is the moment to explain the change aloud: which label changed, why the input origin is clearer, and which behavior was preserved.

The selected path is the CP01 README.md; do not use the expected two-line fragment as proof that your whole working tree is correct. Inspect the actual changed lines, run the relevant project check, and compare the result with the task brief. Figures SS05-03 and SS05-04 belong to this real diff and staged selection.

7. Lab LAB05: save a meaningful change

Starting from your baseline commit, perform the supplied reporting-label edit independently. Write a one-sentence acceptance statement before editing. Use the editor to make and save the change, inspect the ordinary diff, and run the relevant check. Stage the exact file and inspect the cached diff. Then commit with a message explaining the reporting purpose.

# Context: PowerShell in the practice repository; inspect before committing.
git status
git diff --cached
git commit -m 'Clarify synthetic input in the report label'
git log --oneline -2
git status

Your deliverable is two explanatory commits plus a short note identifying the baseline and label change. The expected observation is a history whose second entry contains only the intended change and any deliberately associated documentation. Your IDs and timestamps will differ from the book. Figure SS05-05 shows the teaching history and message order.

As an additional staging check, edit a harmless sentence in the README, stage it, then edit that sentence again. Inspect both diff views without committing. Explain which version would enter a commit now. Restore your chosen final sentence in the editor and restage only if you intend to keep it. This shows that “staged file” does not mean every future edit to that file is automatically selected.

8. Failure and recovery: staged build output

Practice this only after the baseline commit exists. Create a harmless text file such as build-note.tmp in the practice root, deliberately stage it, and inspect the staged diff. It represents accidental generated output. Unstage this specific path while preserving the file:

# Context: PowerShell in the disposable practice repository, after a baseline commit.
git restore --staged -- build-note.tmp
git status

With --staged, this operation updates the staging area; it does not discard the working file. Add an appropriate exact ignore entry for the teaching temporary file, or use the project's existing generated-output directory in actual work. Then inspect .gitignore and stage its intended change. Avoid broad patterns that accidentally hide real fixtures or source. git restore reference

If generated output was already committed, an ignore entry alone will not untrack it. That is a different state requiring a deliberate tracked-file cleanup, outside this simple staging exercise. Identify the state first. Do not respond by deleting the project or using a destructive reset. The recovery here is complete when the unwanted path is absent from the staged snapshot and the useful work remains present.

Completion checklist

  • I initialized the intended source-only folder and recorded local identity.
  • I can distinguish working, staged, and committed contents.
  • I inspected ordinary and cached diffs before each meaningful commit.
  • I have two explanatory commits and relevant verification evidence.
  • I recovered from staging harmless output without deleting useful files.

Review questions with answers

1. Does saving in VS Code create a commit? No. Saving updates the working file. Staging selects contents, and committing records the selected snapshot. These actions are separate even when an interface places their controls close together.

2. Why can one file appear staged and unstaged? You may have edited it after staging. The index contains one version and the working tree another. Compare both diffs to decide which content belongs in the next commit.

3. Does a clean status prove the tests pass? No. It describes repository state. A test result must come from a named command and source version. Keeping both observations gives a much more useful checkpoint.

Transfer exercise

Choose a recent change in a real project. Describe a commit boundary that would make its purpose easy to review and undo. Identify one file that belongs with the change and one generated or unrelated artifact that does not. Use that boundary during your next small task.

Full Windows Code window showing guarded git init on main, successful initialization in the book practice directory, exit0 and eleven untracked files.
SS05-01 · SS05-01. Git initializes the local practice repository.
Full Windows Code terminal lists eleven green A source paths and red !! build/; Explorer dims build. This is the actual selected state before the baseline commit, despite the stale Untracked title decoration.
SS05-02 · SS05-02. Selected source excludes generated build output.
Full Windows Code Text Diff Editor shows the old Report label: synthetic. and new Report label: synthetic input. line, with one README Modified entry in Source Control.
SS05-03 · SS05-03. The diff isolates the reporting-label change.
Full Windows Code window shows Staged Changes 1 with README.md, Changes 0, and actual git add README.md followed by immediate exit zero, empty ordinary diff, green staged README status and ignored build directory. The real line-ending warning remains visible.
SS05-04 · SS05-04. Staging selects the reviewed README change.
Full Windows Code terminal shows the actual label commit 99cd9c9, one insertion and one deletion, both meaningful commit messages in order, three immediate zero exits and a clean working tree. Source Control shows the two-node history and an untouched Publish Branch button.
SS05-05 · SS05-05. Two commits record distinct reviewed purposes.