TT Lab
开始
学习 学习路径 课程

Git 实战

活儿开了一半,紧急修复来了

在 TT Lab 中继续学习

目标

给一个仓库最多挂载三个工作目录,再把它们清理掉。完成后,你会养成不用 stash 就能切换分支的习惯,也会知道如何清除工作树留下的管理文件。

为什么重要

想想为什么切换分支这么麻烦,原因在于工作树只有一个。仓库保存着对象和分支引用,工作树则是把其中某个提交展开后的副本。如果能增加展开的位置,切换本身就不再必要。git worktree 做的正是这件事。不过分支引用在仓库里只有一份,所以想在两个位置打开同一个分支时,git 会阻止。理解这个限制是本实验的一半。另一半是清理——只删除目录的话,管理文件会留下,该位置会一直以 prunable 状态出现在列表里。

步骤

  1. 在 /root/gitx4/repo 创建一个含 3 个提交的仓库,并创建 release 分支。
  2. 把 release 作为工作树挂载到 /root/gitx4/rel。
  3. 尝试再把 main 挂载到 /root/gitx4/dup,并把拒绝信息保存到 notes/dup.txt。
  4. 在 repo 中保留未保存的修改,同时在 /root/gitx4/hot 新建并挂载 hotfix 分支,在那里提交 hotfix.txt。
  5. 把 git worktree list --porcelain 的输出保存到 notes/list.txt。
  6. 挂载 /root/gitx4/tmp 后只用 rm -rf 删掉目录,把 prunable 标记和 prune 的结果保存到 notes/prune.txt。
  7. 挂载 /root/gitx4/usb 并加 lock,把 remove 被拒绝的情形保存到 notes/lock.txt,然后解锁并删除。
  8. 在 notes/report.md 中总结 worktree、stash、clone 各自适用的场合。

参考

创建仓库和发布分支

在 /root/gitx4/repo 创建一个含 3 个提交的仓库,并创建 release 分支。

从 git init -b main 开始。这个镜像没有全局身份,所以每个仓库都要设置 git config user.email 和 user.name 才能提交。提交时间用 GIT_AUTHOR_DATE 和 GIT_COMMITTER_DATE 两个环境变量固定。

把发布分支挂载到第二个位置

把 release 作为工作树挂载到 /root/gitx4/rel。

命令是 git worktree add <경로> <브랜치>(占位符依次为路径与分支名)。挂载后,用 cat 确认新目录里的 .git 不是目录而是文件。那一行内容指向原仓库的管理目录。

为什么同一个分支不能在两个位置打开

尝试再把 main 挂载到 /root/gitx4/dup,并把拒绝信息保存到 notes/dup.txt。

原样执行 git worktree add /root/gitx4/dup main,会出现以 fatal: 开头的一行。不要概括这一行,原样放进文件,再补充一行说明为什么会被阻止——分支引用在仓库里只有一份。

保留未保存的修改,同时做热修复

在 repo 中保留未保存的修改,同时在 /root/gitx4/hot 新建并挂载 hotfix 分支,在那里提交 hotfix.txt。

先在 repo 中创建 draft.txt——既不提交也不 stash。在这种状态下,用 git worktree add -b <새브랜치> <경로> <기준>(占位符依次为新分支名、路径与基准)再开一个位置,并在那个目录里提交。完成后查看 repo,draft.txt 仍然原样存在。

用机器可读的格式查看当前有几个位置

把 git worktree list --porcelain 的输出保存到 notes/list.txt。

--porcelain 是为脚本而不是为人阅读设计的输出。它不是对齐好的表格,而是 worktree、HEAD、branch 各占一行。用重定向原样写入文件。

只删除目录会留下管理文件

挂载 /root/gitx4/tmp 后只用 rm -rf 删掉目录,把 prunable 标记和 prune 的结果保存到 notes/prune.txt。

先用 git worktree add -b tmpwork /root/gitx4/tmp 创建位置,再对该目录执行 rm -rf。在这种状态下查看 git worktree list,其中一行会带上 prunable。请确认 git worktree prune -v 说删掉了什么,以及分支是否保留,并记录下来。prune 的说明输出到标准错误,所以要存入文件就需要 2>&1。

被锁定的位置会被 remove 拒绝

挂载 /root/gitx4/usb 并加 lock,把 remove 被拒绝的情形保存到 notes/lock.txt,然后解锁并删除。

用 git worktree lock --reason '<사유>' <경로>(占位符依次为原因与路径)加锁。对被锁定的位置执行 git worktree remove 会出现拒绝信息——请原样保存这一行。然后 unlock 并 remove,确认列表和目录一起消失。

什么时候增加位置,什么时候把工作推开

在 notes/report.md 中总结 worktree、stash、clone 各自适用的场合。

按三种方法各自节省什么、损失什么来区分撰写。这次亲眼见到的两点——同一个分支不能在两个位置打开,以及删除目录后管理文件仍会残留——也必须写进去。