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]>
45 lines
3.3 KiB
JSON
45 lines
3.3 KiB
JSON
{
|
|
"id": "git-branching-and-merge",
|
|
"title": "Resolve a Real Merge Conflict",
|
|
"category": "Git",
|
|
"isolation_type": "shared_namespace",
|
|
"difficulty": "Medium",
|
|
"type": "task",
|
|
"weight": 6,
|
|
"description": "## Resolve a Real Merge Conflict\n\nA repository at `/srv/git-lab-branch/` already has two branches (`main` and `feature`) that both changed the SAME line of `shared.txt` differently — merging them WILL conflict.\n\n**Your task:**\n\n1. Make sure you're on the `main` branch\n2. Merge `feature` into it: `git merge feature`\n3. Git will report a conflict — open `shared.txt` and you'll see conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`)\n4. Edit the file to remove the markers and decide on final content (either version, both, or something new — your choice)\n5. Stage the resolved file and commit to complete the merge",
|
|
"hints": [
|
|
{
|
|
"title": "What the conflict markers mean",
|
|
"body": "Everything between `<<<<<<< HEAD` and `=======` is YOUR current branch's version; everything between `=======` and `>>>>>>> feature` is the incoming branch's version. Delete all three marker lines and keep whichever content (or combination) you actually want.",
|
|
"command": "cat /srv/git-lab-branch/shared.txt"
|
|
},
|
|
{
|
|
"title": "Completing the merge",
|
|
"body": "Once the file no longer has conflict markers, staging and committing tells Git the conflict is resolved.",
|
|
"command": "cd /srv/git-lab-branch\ngit add shared.txt\ngit commit -m 'Merge feature, resolve conflict'"
|
|
}
|
|
],
|
|
"setup_commands": [
|
|
{ "command": "git config --global init.defaultBranch main" },
|
|
{ "command": "git config --global user.email [email protected]" },
|
|
{ "command": "git config --global user.name 'RootNode Student'" },
|
|
{ "command": "rm -rf /srv/git-lab-branch && mkdir -p /srv/git-lab-branch" },
|
|
{ "command": "cd /srv/git-lab-branch && git init -q && echo 'original line' > shared.txt && git add shared.txt && git commit -q -m 'Initial commit'" },
|
|
{ "command": "cd /srv/git-lab-branch && git branch feature && git checkout -q feature && echo 'feature version' > shared.txt && git commit -qam 'Update from feature branch'" },
|
|
{ "command": "cd /srv/git-lab-branch && git checkout -q main && echo 'main version' > shared.txt && git commit -qam 'Update from main branch'" },
|
|
{ "command": "cd /srv/git-lab-branch && git merge feature 2>/dev/null; true" }
|
|
],
|
|
"validation": {
|
|
"commands": [
|
|
{ "description": "the feature branch still exists", "command": "git -C /srv/git-lab-branch branch --list feature | tr -d ' *'", "expected_output": "feature", "match": "exact" },
|
|
{ "description": "a real merge commit (two parents) exists", "command": "git -C /srv/git-lab-branch log --merges --oneline 2>/dev/null | wc -l | tr -d ' '", "expected_output": "^[1-9][0-9]*$", "match": "regex" },
|
|
{ "description": "the conflict markers were actually removed", "command": "grep -c '<<<<<<<' /srv/git-lab-branch/shared.txt", "expected_output": "0", "match": "exact" },
|
|
{ "description": "the working tree is clean (nothing left uncommitted)", "command": "git -C /srv/git-lab-branch status --short | wc -l | tr -d ' '", "expected_output": "0", "match": "exact" }
|
|
]
|
|
},
|
|
"default_namespace": "default",
|
|
"teardown_commands": [
|
|
{ "command": "rm -rf /srv/git-lab-branch" }
|
|
]
|
|
}
|