14 / 90

Day 14: 使い捨てリポジトリでの Git コラボレーション

カリキュラムのワークツリーに触れずに、ブランチ、差分、コンフリクト、安全な回復、PR 形式レビューを使います。

自律学習と Python 480 分(8 時間の集中学習)
01 120 分

ブランチ、差分、レビュー

エージェント支援は任意で、書面の計画に従う。学習者が権限を所有し、すべての差分とコマンド結果を検証する。選択したエージェントが使えない場合、その部分は blocked/unexecuted として記録する — シミュレートしない。

前提条件

Day 13 のプロジェクトアーティファクトと基本的な Git の status/log/diff。

学習目標

使い捨てのクローンを作成し、テキストプロジェクトに対して焦点を絞ったブランチ変更を行い、コミット前に差分をレビューする。

手順

必須作業: 参考解答の手順どおりに private ベースとクローンを構築する(projects/text_tools/{__init__.py,core.py,cli.py} のみを新しい private ベースにコピーする — 学習リポジトリやその .git、データベース、.venv、シークレットをクローン・公開・変更しない)。次にブランチ parser-help を作り、指定された --input ヘルプの 1 行改善を行い、1 つの焦点の絞られたコミットの前に branch、status、log、staged と unstaged の差分、git diff --check を記録する。公開 --help チェックで動作を証明する — 差分と終了コード 0 は証拠であり証明ではない。各ブロックは set -e を効かせた ( ... ) 内で実行する:新しい WORKDIR を使用前に検証し、mkdir/cp/cd が失敗すればサブシェル内で中断する — 失敗したコマンドが抜け落ちて現在のリポジトリで Git を実行することはなく、export も呼び出し元シェルに残らない。d14env は外部コマンドを env -i で包み、環境の GIT_DIR/GIT_WORK_TREE/index/object/alternates、GIT_CONFIG*、XDG、テンプレート・フック・署名変数を落として、それらが「この作例コマンド」を誘導できないようにする。ただし env -i だけでは WORKDIR 外への書き込みは止められない — 検証済みの前提条件と fail-stop が作例コマンドを WORKDIR 内に留める。PATH は実行ファイルの選択のみ(解決されたパスは表示される。Python は絶対パス PYTHON_BIN に固定)— 信頼ツール一覧でもファイルシステム境界でもない。これは環境の衛生であり OS サンドボックスではない。表示された WORKDIR の値を自分で export する — 後のアクティビティブロックがそれを要求する。任意作業: 書面の計画に沿って実際のエージェントに差分をレビューさせてよい。選択したツールが使えない場合は、その部分を blocked/unexecuted と記録し、トランスクリプトを捏造しない。

演習と予測

--input ヘルプ改善で projects/text_tools/cli.py のどの行が変わり、コピーした 3 ファイルのうちどれがバイト一致のままであるべきか(sha256sum で検証)を予測する。git diff と終了コード 0 が動作の証明ではなく証拠である理由、および GIT_DIR が別リポジトリを指し得るとき d14env(env -i + private HOME/XDG/config/template + 署名無効)経由の実行が重要な理由、および ( set -e の fail-stop と WORKDIR 検証が、失敗した cd が呼び出し元リポジトリで Git を実行するのを防ぐ理由を説明する。以下の完全な private セットアップとチェックを実行する:

(
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 バイト
Declared Assistance Condition

Current Submitted Evidence Details

No submission recorded yet.
独立習得基準

学習者はコマンド出力を添えてブランチ・コミット・差分・レビューの境界を説明でき、新しいヘルプテキストを示す公開 --help チェックを含み、任意のエージェントレビューが実行されたか、blocked/unexecuted として正直に記録されたかを述べる。

ソースリソースと出所

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

Pro Git, Second Edition

著者・提供機関: Scott Chacon and Ben Straub | オリジナル出所URL ↗

該当セクション・タイムスタンプ: Chapter 3 (Git Branching: branches, basic merging and conflicts), Chapter 7.7 (Reset Demystified), Chapter 5.2 (Contributing to a Project)

検証バージョンと日付: Second edition (Apress, 2014); verified 2026-10-30

選定理由:

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

ソース前提知識:

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

安全フォールバック(オフライン回復性):

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.

比較対象候補リソースと選定評価 (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 分

独立したコンフリクト解消

独立習得チェック: AI や写したコンフリクト解消は不可。公式 Git ドキュメントは参照可。

前提条件

分岐した 2 つのブランチを持つ使い捨てリポジトリ。

学習目標

実際の text_tools フィクスチャのコンフリクトを自力で解消し、意図した両方の変更を保持する。

手順

必須作業: まず自力で新しいバリアントに挑戦する — 実際の cli.py の別の行(例: --seed ヘルプテキスト)と自分で考えた両立する 2 つの要件語を選び、分岐した 2 つのブランチを作り、マージし、両方の用語を保持する解消を行い、各用語を別々の --help チェックと git rev-list --parents -n 1 HEAD(3 つの id = 2 親のマージ)で検証する。その後、description 行と Unicode-aware・original-byte を使う以下の参考ケースと比較する。このブロックはセットアップブロックが export した WORKDIR フィクスチャを再利用する(または先にその表示パスを WORKDIR に設定する)し、d14env を再宣言する。公式 Git ドキュメントは参照可。AI 出力や写した解消は独立した習得とみなさない。任意作業: 後で参考説明と比較する。

演習と予測

マージ前に、自分のバリアントでのコンフリクトマーカーと最終的な行の内容を予測する。盲目的に ours か theirs を選ぶと要件を失う理由と、解消が両方の受け入れ条件を満たす仕組みを説明する。参考シーケンス(同じ private クローン):

(
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
)
独立習得基準

学習者自身のバリアントでの無支援の解消が正しい:両方の要件語が --help で検証され、2 親のマージコミットが記録され、証拠がコンフリクト・選択した動作・チェック・安全な境界を名指ししている。

ソースリソースと出所

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

Pro Git, Second Edition

著者・提供機関: Scott Chacon and Ben Straub | オリジナル出所URL ↗

該当セクション・タイムスタンプ: Section 3.2 (Basic Merging and Conflicts)

検証バージョンと日付: Second edition (Apress, 2014); verified 2026-10-30

選定理由:

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

ソース前提知識:

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

安全フォールバック(オフライン回復性):

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

比較対象候補リソースと選定評価 (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 分

安全な回復

エージェント支援型エンジニアリングチェック: エージェントは選択肢を説明できるが、学習者が各手順を実行・検証する。ツールが使えない場合は blocked/unexecuted と記録する。

前提条件

コミット済みの使い捨てフィクスチャと、意図的で可逆的なミス。

学習目標

安全で非破壊的な操作を使って、誤った編集や望まないコミットから回復する。

手順

必須作業(同じ private クローン): (0) 正準の参考ベースラインを確立する — parser-help から d14-ref ブランチを作り、解消済みの description 行をコミットする。確定済みの独立作業は自分のブランチに残り、破棄しない。(A) cli.py をバックアップし、2 ハンクの unstaged ケース(description 行の MISTAKE タイポ + --seed ヘルプ行の KEEP 編集)を再現、git diff を確認し、タイポだけを取り消して KEEP ハンクの残存を検証し、次に有効な編集をコミットする — コミット済みの変更は後のクリーンアップ実演で落とせない。(B) 新しい単一ハンクのミスで staged と worktree の区別を実演:ステージし、git restore <path> がインデックスに残すことを示し、--staged の後に全パス破棄 — 残る変更が本当に不要なものだけなので正当。ツリーがクリーンで、コミット済み KEEP が --help で動作することを確認する。(C) 既知の単一親 BAD コミットの後に独立した GOOD コミットを作り、BAD を新規コミットで revert し、GOOD と KEEP が残り履歴が書き換えられなかったことを証明する。最後に(期待される失敗として)マージコミットの revert が -m によるメインライン選択を要求することを観察する。任意作業: 実行後にエージェントと回復の選択を見直す。

演習と予測

有効な編集と同じファイルを共有する unstaged のタイポと、別途、悪い単一親コミットの後に続く独立した良いコミットについて:git restore、git revert、保存済みコピーのどれを使うか選び、実行前に結果の差分と履歴を予測する。KEEP 編集はなぜワークツリーで生き残るだけでなく、ステージ済みミスの実演前にコミットしなければならないか?

(
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
)
独立習得基準

学習者は確定済みの作業を破棄せず正準ベースラインを確立し、リポジトリの状態から各操作を正当化し、KEEP 編集が自身のコミットとクリーンな status + --help チェックによりクリーンアップ後も残ることを証明し、revert が履歴を書き換えず新規コミットを作ったことを示し、メインラインを推測せずにマージ revert の失敗を観察する。

ソースリソースと出所

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

Pro Git, Second Edition

著者・提供機関: Scott Chacon and Ben Straub | オリジナル出所URL ↗

該当セクション・タイムスタンプ: Section 7.7 (Reset Demystified) and Section 2.4 (Undoing Things): restore, revert, and history boundaries

検証バージョンと日付: Second edition (Apress, 2014); verified 2026-10-30

選定理由:

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

ソース前提知識:

Completion of day-14-act-02

安全フォールバック(オフライン回復性):

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

比較対象候補リソースと選定評価 (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 分

PR 形式レビューと想起

独立習得チェック: 予測・自分のチェック・確定レビューはすべて無支援。後の支援付き比較は別物であり置き換えない。

前提条件

完了したブランチ、コンフリクト、回復の証拠。

学習目標

使い捨ての変更をプルリクエストのようにレビューし、正確性、範囲、テスト、リスク、証拠を分離する。

手順

必須作業: まず自分の予測/初期仮説を無支援で記録する。次に弱いチェックと強いチェックを自分で実行する — 自分による実行は無支援の試行の一部であり支援ではない。続いて、完成した無支援レビューを確定(提出・日付記録)する — 受け入れ基準、ブロッキング指摘、非ブロッキング指摘、実際に観測した証拠、境界。動作が正しかった場合も、実行したチェックとそれが十分な理由を確定レビューに記録する — 「問題なさそう」だけでは不合格。任意作業: その後、実際のエージェントレビューと比較してよいが assisted とラベル付けし(確定ドラフトの代替にしない)、支援による修正には新たな無支援の再チェックが必要。外部公開は許可されない。

演習と予測

強いチェックを実行する前に、--help に --quiet が表示されることがフラグの動作を証明するかを予測する。弱いスモークチェックが見逃す欠陥と、それを暴く強い CLI チェックを挙げる。パッチ(レビューア作成、観測されたエージェント出力ではない):

(
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
)
独立習得基準

確定された無支援レビューが受け入れ基準(--quiet で要約抑制)を述べ、自分の実行で実際に観測した stdout を証拠として引用し、ブロッキングと非ブロッキングを区別し、仮想パッチと実際のエージェント出力、自分のチェックと隠れた評価器を区別し、予測と自分のチェックの後・支援付き比較の前に確定・提出されている。

ソースリソースと出所

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

Pro Git, Second Edition

著者・提供機関: Scott Chacon and Ben Straub | オリジナル出所URL ↗

該当セクション・タイムスタンプ: Section 5.2 (Contributing to a Project: commit and review etiquette) and Section 6.2 (Contributing via pull requests)

検証バージョンと日付: Second edition (Apress, 2014); verified 2026-10-30

選定理由:

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

ソース前提知識:

Completion of day-14-act-03

安全フォールバック(オフライン回復性):

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

比較対象候補リソースと選定評価 (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.