活儿开了一半,紧急修复来了
目标
给一个仓库最多挂载三个工作目录,再把它们清理掉。完成后,你会养成不用 stash 就能切换分支的习惯,也会知道如何清除工作树留下的管理文件。
为什么重要
想想为什么切换分支这么麻烦,原因在于工作树只有一个。仓库保存着对象和分支引用,工作树则是把其中某个提交展开后的副本。如果能增加展开的位置,切换本身就不再必要。git worktree 做的正是这件事。不过分支引用在仓库里只有一份,所以想在两个位置打开同一个分支时,git 会阻止。理解这个限制是本实验的一半。另一半是清理——只删除目录的话,管理文件会留下,该位置会一直以 prunable 状态出现在列表里。
步骤
- 在
/root/gitx4/repo创建一个含 3 个提交的仓库,并创建release分支。 - 把
release作为工作树挂载到/root/gitx4/rel。 - 尝试再把
main挂载到/root/gitx4/dup,并把拒绝信息保存到notes/dup.txt。 - 在
repo中保留未保存的修改,同时在/root/gitx4/hot新建并挂载hotfix分支,在那里提交hotfix.txt。 - 把
git worktree list --porcelain的输出保存到notes/list.txt。 - 挂载
/root/gitx4/tmp后只用rm -rf删掉目录,把prunable标记和prune的结果保存到notes/prune.txt。 - 挂载
/root/gitx4/usb并加lock,把remove被拒绝的情形保存到notes/lock.txt,然后解锁并删除。 - 在
notes/report.md中总结 worktree、stash、clone 各自适用的场合。
参考
- 这个镜像没有全局 git 身份。创建仓库后,必须在该仓库中设置
git config user.email和git config user.name才能提交。 - 提交时间用
GIT_AUTHOR_DATE和GIT_COMMITTER_DATE固定。这是为了让评分不受时间影响,在实际工作中也是构建可复现历史时常用的做法。 - 常见错误:在第 4 步用
git stash或提交把repo中的修改清走。本实验的要点正是不清走也行,所以必须原样保留。 - 常见错误:在第 6 步使用
git worktree remove。这里要看的流程是先用rm -rf删掉目录,再由prune清理残留的管理文件。
创建仓库和发布分支
在 /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 各自适用的场合。
按三种方法各自节省什么、损失什么来区分撰写。这次亲眼见到的两点——同一个分支不能在两个位置打开,以及删除目录后管理文件仍会残留——也必须写进去。