feat(root03): author Git & Collaborative Development

Adds all 6 ROOT 03 modules (why version control exists, the Git mental model, everyday Git,
branching & merging, remote repositories, engineering Git workflow) — 31 activities. Uses only
real LOCAL Git repositories throughout — no Gitea account, no network access, and no
RootNode-canonical-repo credential is ever needed or exposed in a student Lab
(docs/ROOT_FOUNDATIONS_LAB_STRATEGY.md §4). Modules 1, 2, and 6 are conceptual bookends with no
lab, matching the flexible readiness standard already used in ROOT 01/02.

Adds 3 new hands-on Git scenarios plus 2 MCQs: git-everyday-basics (init/add/commit, validated
by inspecting real `git log`/`git show` state, not just command output strings — Step 6's
explicit requirement), git-branching-and-merge (a REAL merge conflict caused on purpose by two
branches editing the same line, resolved by the student, validated by confirming the conflict
markers are gone and a real two-parent merge commit exists), and git-remote-clone-push (a real
local bare repository standing in for a remote — clone/commit/push validated by inspecting the
REMOTE side directly, not just the student's own clone). All tested end-to-end via the real
scenario-validation API, including negative tests.

Wires rootnode-git-fundamentals-assessment (2 required + 3 random-draw scenarios) using the
existing Phase 3B assessment engine.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-08-26 17:08:00 -05:00
co-authored by Claude Sonnet 5
parent e007bcf000
commit e68b6f445a
33 changed files with 1393 additions and 0 deletions
@@ -0,0 +1,62 @@
# Branching and Merging
## Why branches exist
Without branches, every commit happens on the same single line of history — risky work and
finished work are indistinguishable, and two people can't develop different things
simultaneously without directly interfering with each other. A **branch** is a movable pointer
to a commit, letting you develop something in isolation and only combine it back into the main
line when it's actually ready.
## Creating and switching branches
```
$ git branch feature-login # create a new branch (doesn't switch to it)
$ git checkout feature-login # switch to it
$ git switch feature-login # the newer, clearer equivalent of checkout for this purpose
$ git checkout -b feature-login # create AND switch in one step
```
Commits made while on `feature-login` only affect that branch — `main` is completely unaffected
until you deliberately combine them.
## Merging: combining two branches' history
```
$ git checkout main
$ git merge feature-login
```
Git attempts to combine the two branches' history automatically. When the two branches changed
DIFFERENT parts of a project, this usually succeeds with no fuss.
## Divergence and conflicts
When both branches changed the SAME lines of the SAME file differently, Git can't automatically
decide which version is correct — this is a **merge conflict**. Git marks the conflicting
section directly in the file:
```
<<<<<<< HEAD
your current branch's version
=======
the incoming branch's version
>>>>>>> feature-login
```
A conflict is not an error you did something wrong — it's Git correctly refusing to silently
guess which change you actually want. You resolve it by editing the file to the content you
actually want (removing the markers), then staging and committing to complete the merge.
## Instructor Notes
**Lesson goal:** Frame merge conflicts as an EXPECTED, normal part of collaborative work — not
a sign of failure — before students hit their first real one in this module's Lab.
**Approximate timing:** 15 minutes read; 10 minutes live.
**Common misconception to watch for:** panicking at the sight of conflict markers — reinforce
explicitly that this is Git behaving correctly, not breaking.
**Demo idea:** deliberately narrate a conflict as "Git is asking YOU to make a decision it
can't make safely on its own" rather than "something went wrong."
@@ -0,0 +1,61 @@
# Demonstration: A Conflict, Caused and Resolved on Purpose
## OBSERVE
Two branches both changed line 1 of `config.txt` — `main` to `"env=production"`, `feature` to
`"env=staging"`.
## HYPOTHESIS
Predict what `git merge feature` will do.
## INSPECT
```
$ git merge feature
Auto-merging config.txt
CONFLICT (content): Merge conflict in config.txt
Automatic merge failed; fix conflicts and then commit the result.
```
Exactly as predicted — Git refuses to guess.
## CHANGE
```
$ cat config.txt
<<<<<<< HEAD
env=production
=======
env=staging
>>>>>>> feature
```
Decide the real answer — here, say `env=production` is correct — and edit the file to exactly
that, deleting all three marker lines.
## VERIFY
```
$ git add config.txt
$ git commit -m "Merge feature, keep production config"
$ git log --oneline --graph
* a1b2c3d Merge feature, keep production config
|\
| * 9f8e7d6 Update from feature
* | 3d2c1b0 Update from main
|/
* 0a1b2c3 Initial commit
```
The graph shows exactly what happened: two lines of history, deliberately combined.
## Instructor Notes
**Demo goal:** Walk a real conflict from cause to resolution without skipping any step,
reinforcing that resolution means making an explicit CHOICE, not applying a trick.
**Approximate timing:** 10 minutes live.
**Common mistake to watch for:** leaving conflict markers accidentally in the "resolved" file
(easy to miss one) — `grep '<<<<<<<' file` before committing catches this reliably.
@@ -0,0 +1,36 @@
# Knowledge Check: Branching and Merging
---
**1. What is a branch, really?**
*Answer:* A movable pointer to a specific commit — not a copy of the whole project, just a
reference letting you develop independently from other branches.
---
**2. Why does a merge conflict happen?**
*Answer:* Both branches changed the SAME lines of the SAME file differently, and Git can't
safely guess which version you actually want — so it stops and asks you to decide.
---
**3. Is a merge conflict a sign something went wrong?**
*Answer:* No — it's Git correctly refusing to silently guess at a decision only a human should
make. It's a normal, expected part of collaborative work.
---
**4. After resolving a conflict by editing the file, what two steps complete the merge?**
*Answer:* Stage the resolved file (`git add`) and commit (`git commit`) — exactly like
completing any other commit, once the conflict markers are gone.
## Instructor Notes
**Facilitation:** Question 3 is worth stating explicitly and repeating — reframing conflicts
as normal, not scary, meaningfully changes how confidently students approach this module's Lab.
**Approximate timing:** 5 minutes.
@@ -0,0 +1,36 @@
# Guided Exercise: Decide the Resolution Before You Touch the File
This is a paper exercise — commit to a decision before resolving anything in the Lab.
## Your task
A merge conflict shows:
```
<<<<<<< HEAD
timeout_seconds = 30
=======
timeout_seconds = 120
>>>>>>> feature
```
You know `main`'s value (30) was set deliberately for production safety, but `feature`'s value
(120) was added while debugging a slow endpoint that genuinely needs more time. Write out: what
final content would you put in the file, and why is that the RIGHT resolution (not just "pick
one side")?
## A worked shape to check yourself against
A well-reasoned resolution here is neither side alone: something like keeping `30` as the
DEFAULT but adding a comment or a separate, more specific setting for the slow endpoint
specifically — the point is that conflict resolution sometimes means genuinely combining intent
from both sides, not mechanically picking `HEAD` or the incoming branch. There's no single
"correct" file content — the value is in justifying whichever choice you make with real
reasoning, not defaulting to whichever side happens to be `HEAD`.
## Instructor Notes
**Facilitation:** The point of this exercise is resisting "just pick a side" as a reflex —
some conflicts genuinely require combining or renegotiating intent, not mechanical selection.
**Approximate timing:** 8-10 minutes live discussion; 5 minutes self-paced.
@@ -0,0 +1,26 @@
# Reflection: Your First Conflict Wasn't a Disaster
## Reflection questions
1. Before this module, how would you have reacted to seeing conflict markers in a real file
for the first time?
2. What made resolving the conflict in this module's Lab feel manageable (or not)? What would
make a REAL conflict, in a large unfamiliar file, harder?
## Real Ops takeaway
**Merge conflicts are one of the most feared parts of Git for beginners, and one of the most
routine parts of Git for experienced engineers — the difference is just repetition.** You've now
caused one on purpose, resolved it deliberately, and verified the result — exactly the
experience that turns "conflicts are scary" into "conflicts are Tuesday." Module 5 adds a real
remote to this same workflow; conflicts show up there too, and you're now prepared for them.
This module is complete. Continue to the next module.
## Instructor Notes
**Discussion questions for a live classroom:** question 2 is worth extending into "what would
make a conflict on a 500-line file, with someone else's unfamiliar code, actually hard" — a good
honest preview of real collaborative work.
**Approximate timing:** 5-8 minutes live discussion; 5 minutes self-paced writing.