跳到内容

第 0 卷 / 第 3 章 / 第 7 课

3.7 Git 综合实验 ​

前置知识:本章前六页

预计时间:25~35 分钟

练习环境:Bash 与 Git 2.28 或更高版本;不访问网络,不修改全局配置

完成标志:两份本地克隆能完成提交、冲突、push、fetch 和合并

概念已经走完一遍。最后,把远程仓库和两份克隆全部放进同一个临时目录,让 Alice 与 Bob 完成一次可重复的协作。即使前面的连续练习中途停过,这个实验也能独立运行。

任务一:创建远程和第一位开发者 ​

bash
workdir=$(mktemp -d)
git init --bare -b main "$workdir/remote.git"
git init -b main "$workdir/alice"

git -C "$workdir/alice" config user.name Alice
git -C "$workdir/alice" config user.email alice@example.invalid
printf '%s\n' 'line=base' > "$workdir/alice/config.txt"
git -C "$workdir/alice" add config.txt
git -C "$workdir/alice" commit -m 'Add base configuration'
git -C "$workdir/alice" remote add origin "$workdir/remote.git"
git -C "$workdir/alice" push -u origin main

运行 git -C "$workdir/alice" status --short,此时应没有输出;远程也已经有了 main。

任务二:第二位开发者提交 ​

bash
git clone "$workdir/remote.git" "$workdir/bob"
git -C "$workdir/bob" config user.name Bob
git -C "$workdir/bob" config user.email bob@example.invalid
printf '%s\n' 'from Bob' > "$workdir/bob/BOB.md"
git -C "$workdir/bob" add BOB.md
git -C "$workdir/bob" commit -m 'Add Bob note'
git -C "$workdir/bob" push

Alice 的 origin/main 不会凭空更新:

bash
git -C "$workdir/alice" fetch origin
git -C "$workdir/alice" log --oneline --left-right main...origin/main
git -C "$workdir/alice" merge --ff-only origin/main
test -f "$workdir/alice/BOB.md"

任务三:制造并解决冲突 ​

Alice 和 Bob 从相同基线修改同一行:

bash
printf '%s\n' 'line=alice' > "$workdir/alice/config.txt"
git -C "$workdir/alice" commit -am 'Alice changes configuration'
git -C "$workdir/alice" push

printf '%s\n' 'line=bob' > "$workdir/bob/config.txt"
git -C "$workdir/bob" commit -am 'Bob changes configuration'
git -C "$workdir/bob" fetch origin
merge_status=0
git -C "$workdir/bob" merge origin/main || merge_status=$?
test "$merge_status" -eq 1
git -C "$workdir/bob" status --short

在 Bob 的文件中选择符合需求的最终值并提交:

bash
printf '%s\n' 'line=alice+bob' > "$workdir/bob/config.txt"
git -C "$workdir/bob" add config.txt
git -C "$workdir/bob" commit -m 'Resolve configuration conflict'
git -C "$workdir/bob" push

任务四:验证历史 ​

bash
git -C "$workdir/alice" fetch origin
git -C "$workdir/alice" merge --ff-only origin/main
test "$(git -C "$workdir/alice" rev-parse HEAD)" = "$(git -C "$workdir/bob" rev-parse HEAD)"
git -C "$workdir/bob" status --short
git -C "$workdir/bob" log --graph --oneline --decorate --all
git -C "$workdir/bob" fsck --no-dangling

验收要点:两份克隆的 HEAD 相同,工作区没有未提交改动;提交图包含两位开发者的变化和一次合并;fsck 没有对象错误。

排障 ​

  • 提交提示 identity unknown:只在当前练习仓库设置 user.name 和 user.email。
  • push 非快进:fetch 后查看提交图,不要立刻 force。
  • pull 要求选择策略:显式使用 --ff-only、--rebase 或按团队约定 merge。
  • 冲突尚未解决:看 git status 列出的 unmerged paths,编辑、测试、add,再 commit。
  • 想取消合并:提交前用 git merge --abort;开始合并前最好保持工作区清晰。
  • 改错未提交内容:先看 git diff,确认不需要后再 git restore -- path。

清理 ​

bash
cd
ls -ld -- "$workdir"
rm -r -- "$workdir"

不要把这条清理命令换成真实仓库路径。确认你能解释 $workdir 的来源和内容后再执行。

两份克隆的 HEAD 比较通过、临时目录清理完后,这次协作实验就完成了。下一章准备调试环境,再用断点检查程序的运行状态。

→ 下一步:准备调试环境

Built with VitePress | Software Systems Atlas