14 / 90

Day 14: Git collaboration in a disposable repository

Use branches, diffs, conflicts, safe recovery, and PR-style review without touching the curriculum worktree.

Self-Directed Learning & Python 480 active minutes (breaks and unattended runtime excluded)
01 120 min

Branches, diffs, and review

Agent assistance is optional and follows a written plan; the learner owns permissions and verifies every diff and command result. If the selected agent is unavailable, the assisted portion is recorded blocked/unexecuted — never simulated.

Prerequisites

Day 13 project artifacts and basic Git status/log/diff.

Learning Objective

Create a disposable clone, make a focused branch change to the text project, and review the diff before committing.

Instructions

Required work: build the private base + clone exactly as the reference answer shows (copy ONLY projects/text_tools/{__init__.py,core.py,cli.py} into a new private base — never clone, publish, or mutate the learning repository or its .git, database, .venv, or secrets), then create branch parser-help, make the specified one-line --input help improvement, and record branch, status, log, staged + unstaged diffs, and git diff --check before a single focused commit. Prove behavior with the public --help check — a diff plus exit code 0 is evidence, not proof. Each block runs inside ( ... ) with set -e: it validates the fresh WORKDIR before any use and aborts inside the subshell on a failed mkdir/cp/cd, so a failed command can never fall through and run Git in your current repository - and exports stay out of your caller shell. d14env wraps external commands in env -i, dropping ambient GIT_DIR/GIT_WORK_TREE/index/object/alternates, GIT_CONFIG*, XDG, template, hook, and signing variables so they cannot steer THESE authored commands; env -i alone does not stop a command from writing outside WORKDIR - the validated preconditions and fail-stop are what keep the authored commands inside it. PATH only selects which executables run (resolved paths are printed; Python is pinned to the absolute PYTHON_BIN) - it is not a trusted-tool list or a filesystem boundary. Environment hygiene, NOT an OS sandbox. Export the printed WORKDIR value yourself - later activity blocks require it. Optional work: a real agent may review your diff against the written plan; if the selected tool is unavailable, record that portion blocked/unexecuted and never fabricate a transcript.

Practice and prediction

Predict exactly which line of projects/text_tools/cli.py changes for the --input help improvement and which of the three copied files must remain byte-identical (verify with sha256sum). Explain why git diff plus a zero exit code is evidence, not proof, of behavior — and why running through d14env (env -i + private HOME/XDG/config/template + signing off) matters when GIT_DIR could point at a different repository - and why ( set -e fail-stop plus the WORKDIR validation keeps a failed cd from ever running Git in the caller's repository. Run this complete private setup and check:

(
set -e
WORKDIR=$(mktemp -d)
[ -n "$WORKDIR" ] && [ -d "$WORKDIR" ] && [ -w "$WORKDIR" ] && [ -x "$WORKDIR" ] || {
  echo "abort: WORKDIR '$WORKDIR' is missing or unusable - refusing to run anything outside it" >&2
  exit 1
}
LEARN=/absolute/path/to/your/clone
[ -f "$LEARN/projects/text_tools/cli.py" ] || {
  echo "abort: LEARN must point at a checkout containing projects/text_tools/cli.py" >&2
  exit 1
}
export WORKDIR LEARN
mkdir -p "$WORKDIR/home" "$WORKDIR/xdg" "$WORKDIR/tpl" "$WORKDIR/tmp"
d14env() {
  env -i PATH="$PATH" HOME="$WORKDIR/home" XDG_CONFIG_HOME="$WORKDIR/xdg" \
      TMPDIR="$WORKDIR/tmp" WORKDIR="$WORKDIR" LEARN="$LEARN" \
      GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_GLOBAL=/dev/null \
      GIT_TEMPLATE_DIR="$WORKDIR/tpl" \
      GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=commit.gpgsign GIT_CONFIG_VALUE_0=false \
      LC_ALL=C PYTHONDONTWRITEBYTECODE=1 "$@"
}
command -v git sed python3
PYTHON_BIN="$(command -v python3)"
mkdir -p "$WORKDIR/base/projects/text_tools"
cp "$LEARN"/projects/text_tools/__init__.py "$LEARN"/projects/text_tools/core.py "$LEARN"/projects/text_tools/cli.py "$WORKDIR/base/projects/text_tools/"
cd "$WORKDIR/base"
d14env git init
d14env git config user.name "Learner"
d14env git config user.email "[email protected]"
d14env sha256sum projects/text_tools/*.py
d14env git add projects/
d14env git commit -m "text_tools snapshot"
d14env git clone "$WORKDIR/base" "$WORKDIR/clone"
cd "$WORKDIR/clone"
d14env git config user.name "Learner"
d14env git config user.email "[email protected]"
d14env git switch -c parser-help
d14env sed -i 's|corpus file\.|corpus file (UTF-8 by default; override with --encoding/--errors).|' projects/text_tools/cli.py
d14env git status --short
d14env git diff
d14env git diff --cached
d14env git diff --check
d14env git add projects/text_tools/cli.py
d14env git commit -m "cli: document --input decoding defaults"
d14env git log --oneline -3
d14env "$PYTHON_BIN" projects/text_tools/cli.py --help | grep -F "UTF-8 by default"
printf 'export WORKDIR=%s  # run this before the later activity blocks\n' "$WORKDIR"
)

Learning Project Submission & Evidence

0 / 4096 bytes
Declared Assistance Condition

Current Submitted Evidence Details

No submission recorded yet.
Independent mastery criterion

Learner can explain branch, commit, diff, and review boundaries with command output attached — including the public --help check demonstrating the new help text — and states that optional agent review was executed, or honestly recorded as blocked/unexecuted.

Source resources and provenance

linking CC BY-NC-SA 3.0 noncommercial share-alike

Pro Git, Second Edition

Author: Scott Chacon and Ben Straub | Original Source Link ↗

Relevant Section / Range: Chapter 3 (Git Branching: branches, basic merging and conflicts), Chapter 7.7 (Reset Demystified), Chapter 5.2 (Contributing to a Project)

Verified Version & Date: Second edition (Apress, 2014); verified 2026-10-30

Selection Rationale:

Freely licensed reference for branching, merging, conflict resolution, and safe recovery vocabulary.

Source Prerequisites:

Basic git status/log/diff vocabulary from earlier study days

Safe Fallback (Offline Resilience):

git help <command> and the Git manual pages ship with Git and cover the same commands offline; every required workflow is stated locally in the lesson.

Compared Candidate Sources & Selection Analysis (2)
GitHub Skills interactive courses ↗ compared_rejected_for_day14 [MIT (varies by course)]

Interactive but requires a GitHub account and an external service; disposable local repositories keep the exercise self-contained.

Atlassian Git Tutorials ↗ compared_rejected_for_day14 [All Rights Reserved]

Vendor-owned prose with no permissive license; Pro Git covers the same ground under CC BY-NC-SA.

02 120 min

Independent conflict resolution

Independent Mastery Check: no AI or copied conflict resolution; official Git documentation may be consulted.

Prerequisites

A disposable repository with two divergent branches.

Learning Objective

Resolve a real text_tools fixture conflict independently and preserve both intended changes.

Instructions

Required work: FIRST attempt a fresh independent variant — pick a different real cli.py line (for example the --seed help text) and two compatible requirement terms of your own, create the two divergent branches, merge, resolve preserving BOTH terms, and verify each term via a separate --help check plus git rev-list --parents -n 1 HEAD (three ids = a merge with two parents). Then compare with the worked reference below, which uses the description line and the terms Unicode-aware and original-byte. The block reuses the WORKDIR fixture exported by the setup block (or set WORKDIR to that printed path first) and re-declares d14env. Official Git documentation may be consulted; no AI output or copied resolution counts as independent mastery. Optional work: compare a reference explanation afterward.

Practice and prediction

Before merging, predict the conflict markers and the final description/line content for your own variant. Explain why blindly choosing ours or theirs loses a requirement, and how a resolution satisfies both acceptance terms. Worked reference sequence (same private clone):

(
set -e
: "${WORKDIR:?set WORKDIR to the private Day 14 fixture path first}"
[ -d "$WORKDIR/clone/.git" ] || { echo "private clone not found - run the setup block first"; exit 1; }
d14env() {
  env -i PATH="$PATH" HOME="$WORKDIR/home" XDG_CONFIG_HOME="$WORKDIR/xdg" \
      TMPDIR="$WORKDIR/tmp" WORKDIR="$WORKDIR" LEARN="$LEARN" \
      GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_GLOBAL=/dev/null \
      GIT_TEMPLATE_DIR="$WORKDIR/tpl" \
      GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=commit.gpgsign GIT_CONFIG_VALUE_0=false \
      LC_ALL=C PYTHONDONTWRITEBYTECODE=1 "$@"
}
command -v git sed python3
PYTHON_BIN="$(command -v python3)"
cd "$WORKDIR/clone"
d14env git switch -c desc-unicode
d14env sed -i 's|compute statistics, deterministic splits, and provenance artifacts\.|compute Unicode-aware statistics, deterministic splits, and provenance artifacts.|' projects/text_tools/cli.py
d14env git commit -am "describe Unicode-aware statistics"
d14env git switch -
d14env git switch -c desc-provenance
d14env sed -i 's|and provenance artifacts\.|and original-byte provenance artifacts.|' projects/text_tools/cli.py
d14env git commit -am "describe original-byte provenance"
if d14env git merge desc-unicode; then
  echo "unexpected: merge resolved cleanly" >&2
  exit 1
else
  echo "expected non-zero exit (content conflict): $?"
fi
d14env sed -n '/<<<<<<</,/>>>>>>>/p' projects/text_tools/cli.py
d14env "$PYTHON_BIN" - <<'PY'
from pathlib import Path
p = Path('projects/text_tools/cli.py')
s = p.read_text()
i = s.index('<<<<<<<')
j = s.index('\n', s.index('>>>>>>>', i))
resolved = '        description="Text and Data Tools: compute Unicode-aware statistics, deterministic splits, and original-byte provenance artifacts."\n'
p.write_text(s[:i] + resolved + s[j+1:])
PY
d14env git add projects/text_tools/cli.py
d14env git commit -m "merge: keep both requirements"
d14env git rev-list --parents -n 1 HEAD
d14env "$PYTHON_BIN" projects/text_tools/cli.py --help | grep -F "Unicode-aware"
d14env "$PYTHON_BIN" projects/text_tools/cli.py --help | grep -F "original-byte"
d14env git status --short
)
Independent mastery criterion

Unaided resolution on the learner's own variant is correct: both requirement terms verified via --help, the merge commit with two parents recorded, and the evidence names the conflict, chosen behavior, checks, and safe boundary.

Source resources and provenance

linking CC BY-NC-SA 3.0 noncommercial share-alike

Pro Git, Second Edition

Author: Scott Chacon and Ben Straub | Original Source Link ↗

Relevant Section / Range: Section 3.2 (Basic Merging and Conflicts)

Verified Version & Date: Second edition (Apress, 2014); verified 2026-10-30

Selection Rationale:

Standard reference for conflict markers and merge semantics underlying the independent resolution exercise.

Source Prerequisites:

Completion of day-14-act-01 in a disposable repository

Safe Fallback (Offline Resilience):

git help merge documents conflict handling offline; the disposable fixture and instructions are fully local.

Compared Candidate Sources & Selection Analysis (2)
Oh Shit, Git!?! ↗ compared_alternative [Copyright Katie Sylor-Miller (all rights reserved; linking only)]

Strong recovery cheatsheet, but conflict resolution is exercised hands-on; Pro Git remains the primary reference.

Learn Git Branching ↗ compared_alternative [MIT]

Visual branch/merge sandbox; useful companion but the exercise must run in a real disposable repo.

03 120 min

Safe recovery

Agent-assisted engineering check: the agent may explain options, but the learner executes and verifies every step; an unavailable tool is recorded blocked/unexecuted.

Prerequisites

A committed disposable fixture and a deliberate, reversible mistake.

Learning Objective

Recover from an accidental edit or unwanted commit using safe, non-destructive operations.

Instructions

Required work in the same private clone: (0) establish the CANONICAL reference baseline — branch d14-ref from parser-help and commit the resolved description line; your sealed independent attempt stays on its own branches and is never discarded. (A) back up cli.py, reproduce the two-hunk unstaged case (MISTAKE typo on the description line + KEEP edit on the --seed help line), inspect git diff, undo ONLY the typo, verify the KEEP hunk survives, then COMMIT the valid edit — a committed change cannot be dropped by the later cleanup demos. (B) staged-vs-worktree on a fresh single-hunk mistake: stage it, show git restore <path> leaves it in the index, then --staged plus a whole-path discard — now justified because the only remaining change is genuinely unwanted; verify the tree is clean AND the committed KEEP still works via --help. (C) commit a known single-parent BAD change followed by an independent GOOD change, revert BAD with a new commit, and prove GOOD and KEEP survive and history was not rewritten; finally observe (expected failure) that reverting a merge demands an -m mainline choice. Optional work: review the recovery choices with an agent after the run.

Practice and prediction

For an unstaged typo sharing a file with a valid edit, and separately for a bad single-parent commit followed by a good commit: choose between git restore, git revert, and the saved copy — and predict the resulting diff and history before running. Why must the KEEP edit be committed BEFORE the staged-mistake demo rather than merely survive it in the worktree?

(
set -e
: "${WORKDIR:?set WORKDIR to the private Day 14 fixture path first}"
[ -d "$WORKDIR/clone/.git" ] || { echo "private clone not found - run the setup block first"; exit 1; }
d14env() {
  env -i PATH="$PATH" HOME="$WORKDIR/home" XDG_CONFIG_HOME="$WORKDIR/xdg" \
      TMPDIR="$WORKDIR/tmp" WORKDIR="$WORKDIR" LEARN="$LEARN" \
      GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_GLOBAL=/dev/null \
      GIT_TEMPLATE_DIR="$WORKDIR/tpl" \
      GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=commit.gpgsign GIT_CONFIG_VALUE_0=false \
      LC_ALL=C PYTHONDONTWRITEBYTECODE=1 "$@"
}
command -v git sed python3
PYTHON_BIN="$(command -v python3)"
cd "$WORKDIR/clone"
d14env git switch -c d14-ref parser-help
d14env sed -i 's|compute statistics, deterministic splits, and provenance artifacts\.|compute Unicode-aware statistics, deterministic splits, and original-byte provenance artifacts.|' projects/text_tools/cli.py
d14env git commit -am "reference baseline: description keeps both requirement terms"
d14env sed -i 's|Unicode-aware statistics|statistisc|' projects/text_tools/cli.py
d14env sed -i 's|(default: 42)\.|(default: 42; any integer).|' projects/text_tools/cli.py
d14env cp projects/text_tools/cli.py "$WORKDIR/cli-backup.py"
d14env git diff
d14env sed -i 's|statistisc|Unicode-aware statistics|' projects/text_tools/cli.py
d14env git diff
d14env git diff --check
d14env "$PYTHON_BIN" projects/text_tools/cli.py --help | grep -F "any integer"
d14env git commit -am "document that --seed accepts any integer"
d14env sed -i 's|default=42,|default=7,|' projects/text_tools/cli.py
d14env git add projects/text_tools/cli.py
d14env git status --short
d14env git restore projects/text_tools/cli.py
d14env bash -c 'git diff --cached | grep -F "default=7"'
d14env git restore --staged projects/text_tools/cli.py
d14env git restore projects/text_tools/cli.py
d14env git status --short
d14env bash -c 'test -z "$(git status --porcelain)"'
d14env "$PYTHON_BIN" projects/text_tools/cli.py --help | grep -F "any integer"
d14env sed -i 's|default=42,|default=7,|' projects/text_tools/cli.py
d14env git commit -am "BAD: change default seed to 7"
BAD=$(d14env git rev-parse HEAD)
d14env sed -i 's|(default: 0.1)\.|(default: 0.1; must be in [0, 1]).|' projects/text_tools/cli.py
d14env git commit -am "GOOD: clarify split-ratio range"
d14env git revert --no-edit "$BAD"
d14env grep -F "default=42," projects/text_tools/cli.py
d14env grep -F "must be in [0, 1]" projects/text_tools/cli.py
d14env grep -F "any integer" projects/text_tools/cli.py
d14env git log --oneline -3
d14env git rev-list --count HEAD
MERGE_SHA=$(d14env git rev-list --all --merges -n 1)
[ -n "$MERGE_SHA" ] || { echo "no merge commit found - run the act-02 reference merge first" >&2; exit 1; }
if d14env git revert "$MERGE_SHA" 2>"$WORKDIR/merge_revert.err"; then
  echo "unexpected: merge revert succeeded without -m" >&2
  exit 1
else
  rc=$?
  grep -F "no -m option" "$WORKDIR/merge_revert.err" && echo "expected non-zero exit (merge needs -m): $rc"
fi
)
Independent mastery criterion

Learner establishes the canonical baseline without discarding sealed work, justifies each operation from repository state, proves the KEEP edit survives AFTER cleanup via its own commit and a clean status plus --help check, shows the revert created a new commit without rewriting history, and observed the merge-revert failure without guessing a mainline.

Source resources and provenance

linking CC BY-NC-SA 3.0 noncommercial share-alike

Pro Git, Second Edition

Author: Scott Chacon and Ben Straub | Original Source Link ↗

Relevant Section / Range: Section 7.7 (Reset Demystified) and Section 2.4 (Undoing Things): restore, revert, and history boundaries

Verified Version & Date: Second edition (Apress, 2014); verified 2026-10-30

Selection Rationale:

Freely licensed explanation of why restore and revert are the safe recovery tools while destructive commands are deferred.

Source Prerequisites:

Completion of day-14-act-02

Safe Fallback (Offline Resilience):

git help restore and git help revert document the same safe operations offline.

Compared Candidate Sources & Selection Analysis (2)
Git documentation: git-restore/git-revert ↗ compared_alternative [GPL-2.0 (Git) / CC BY-NC-SA 3.0 (book-derived pages)]

Exact command references, useful as a companion; Pro Git provides the conceptual model the activity teaches.

Oh Shit, Git!?! ↗ compared_alternative [Copyright Katie Sylor-Miller (all rights reserved; linking only)]

Recovery cheatsheet matching the safe-recovery theme; Pro Git provides the underlying model.

04 120 min

PR-style review and retrieval

Independent Mastery Check: prediction, own checks, and the sealed review are all unaided; the later assisted comparison is separate and never replaces it.

Prerequisites

Completed branch, conflict, and recovery evidence.

Learning Objective

Review a disposable change as if it were a pull request, separating correctness, scope, tests, risks, and evidence.

Instructions

Required work: FIRST record your prediction/initial hypothesis unaided; then run the weak and strong checks yourself in the same private WORKDIR fixture — your own execution is part of the unaided attempt, not assistance; then write and seal (submit, date) the completed UNAIDED review — acceptance criteria, blocking findings, non-blocking findings, the actual observed evidence, and boundaries. If the behavior turns out correct, the sealed review still records the checks run and why they suffice — a bare 'looks fine' fails. Optional work: afterward compare a real agent review labeled assisted (never a replacement for the sealed draft); any assisted correction requires a fresh unaided recheck. External publication is not authorized.

Practice and prediction

Before running the strong check, predict whether --help listing --quiet proves the flag works. Name the defect the weak smoke check cannot see and the stronger CLI check that exposes it. The patch (reviewer-authored, not observed agent output):

(
set -e
: "${WORKDIR:?set WORKDIR to your private Day 14 fixture path first}"
[ -d "$WORKDIR/clone/.git" ] || { echo "private clone not found - run the setup block first"; exit 1; }
d14env() {
  env -i PATH="$PATH" HOME="$WORKDIR/home" XDG_CONFIG_HOME="$WORKDIR/xdg" \
      TMPDIR="$WORKDIR/tmp" WORKDIR="$WORKDIR" LEARN="$LEARN" \
      GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_GLOBAL=/dev/null \
      GIT_TEMPLATE_DIR="$WORKDIR/tpl" \
      GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=commit.gpgsign GIT_CONFIG_VALUE_0=false \
      LC_ALL=C PYTHONDONTWRITEBYTECODE=1 "$@"
}
command -v git sed python3
PYTHON_BIN="$(command -v python3)"
cd "$WORKDIR/clone"
d14env git switch -c add-quiet
d14env "$PYTHON_BIN" - <<'PY'
from pathlib import Path
p = Path('projects/text_tools/cli.py')
s = p.read_text()
old = '    parser.add_argument(\n        "--errors",'
assert s.count(old) == 1
s = s.replace(old, '''    parser.add_argument(
        "--quiet",
        action="store_true",
        help="Suppress the artifact-generation success summary.",
    )
    parser.add_argument(
        "--errors",''')
p.write_text(s)
PY
d14env git commit -am "add --quiet flag"
d14env "$PYTHON_BIN" projects/text_tools/cli.py --help | grep -F -- "--quiet"
mkdir -p "$WORKDIR/acts"
d14env printf 'a\nb\nc\n' > "$WORKDIR/acts/in.txt"
d14env "$PYTHON_BIN" projects/text_tools/cli.py --input "$WORKDIR/acts/in.txt" --split --output-dir "$WORKDIR/acts/out" --quiet
)
Independent mastery criterion

The sealed unaided review states the acceptance criterion (summary suppressed under --quiet), cites stdout actually observed in the learner's own runs, separates blocking from non-blocking findings, distinguishes the hypothetical patch from real agent output and own checks from a hidden evaluator, and was sealed after the recorded prediction and own checks, before any assisted comparison.

Source resources and provenance

linking CC BY-NC-SA 3.0 noncommercial share-alike

Pro Git, Second Edition

Author: Scott Chacon and Ben Straub | Original Source Link ↗

Relevant Section / Range: Section 5.2 (Contributing to a Project: commit and review etiquette) and Section 6.2 (Contributing via pull requests)

Verified Version & Date: Second edition (Apress, 2014); verified 2026-10-30

Selection Rationale:

Provides the shared vocabulary for PR-style review findings while the exercise stays entirely local and disposable.

Source Prerequisites:

Completion of day-14-act-03

Safe Fallback (Offline Resilience):

The review rubric is fully specified in the lesson; no network access is required to complete it.

Compared Candidate Sources & Selection Analysis (2)

Industry-grade review guidance; offered as optional further reading since the exercise reviews a local disposable change.

Conventional Comments ↗ compared_alternative [CC BY 3.0]

Comment-labeling convention for review findings; optional vocabulary, not a substitute for the local rubric.