一个公共仓库连接 main 与 review;两者各自保留 HEAD、索引和工作文件。

Git 工作树共享仓库,各自保留检出状态

关联工作树让同一个 Git 仓库拥有另一个工作目录,并保存各自的检出状态。功能开发、发布维护和评审可以并排展开,不必反复替换同一目录中的文件。真正有用的边界是工作文件与暂存状态分离,而不是完全隔离。对象、许多引用以及普通仓库配置仍然共享,所以操作时既要考虑当前目录,也要考虑它背后的公共仓库,不能把关联工作树等同于互不影响的独立克隆。 关联工作树共享对象、分支与标签引用、默认仓库配置和 stash。每份检出保留自己的 HEAD、索引、文件以及 refs/bisect 等操作状态。review 的提交可从 main 读取,但 main 的暂存文本不变。 区分每份检出自己的状态 每个工作树都有自己的 HEAD 和索引。在一个目录暂存修改,不会让另一目录的索引出现同样变化;编辑一个受跟踪文件,也不会同步编辑旁边那份文件。关联工作树中的普通提交推动它当前选中的分支。新对象和共享分支引用则立即能被其他工作树里的 Git 命令看到,不需要在这些目录之间再执行获取操作。 关联目录中的 Git 入口通常是一个文件,指向它的管理目录。真正检出的源文件住在创建工作树时指定的路径,而不是内部的工作树管理条目里。假定 Git 入口必然是目录的工具,可能因此失效。需要定位公共目录、当前管理目录或索引时,应向 Git 查询对应路径,不能自行拼接内部文件名,把偶然的存储结构当作可靠接口。 ...

七月 26, 2027 · 2 分钟 · XB Field Notes
HEAD 选中 topic,topic 指向 C,main 指向 B。父级箭头从新提交指向父提交。

git 分支是一个会移动的标签

Git 分支为一条历史线的末端提供名字。新建分支通常只是增加一个指向既有提交的引用,不会再复制一份全部受跟踪文件。两个名字可以先指向同一提交,再分别前进。这让分支创建成本很低,但不意味着名字内部装着历史,更不意味着删除指向某个提交的全部引用后,内容仍会永远保留。理解分支时,需要把名称、对象和保留条件分开。 在附着的 topic 上提交,只会移动该分支引用。父级箭头保留共享祖先。未诞生 HEAD 尚无提交;分离 HEAD 直接指向提交。新建分支不会保存未提交编辑。 它是引用,不是固定的存储文件 本地分支属于 refs/heads/ 引用命名空间,具体表示方式是实现细节:引用可能独立存储、被打包,或使用其他受支持的后端。不要假定一定存在某个松散文件,就直接编辑 Git 内部目录来移动分支。应使用 Git 的引用命令,让它遵守仓库实际的存储结构和更新规则,而不是把一种磁盘布局当作永久接口。 提交记录目录树和父提交,沿着父级关系向前追溯,就得到分支末端可达的历史。因此,两条分支可以共享大部分祖先,却拥有不同的末端。分支名称不是提交身份的一部分,新增或重命名分支也不会改写它指向的提交。图中的对象关系解释了共享历史,名称只是人们访问这些对象的入口。 创建分支与切换分支也不同。git branch topic 在当前提交创建名称,但当前分支不会改变;git switch topic 才选中它,并按需要更新工作树。git switch -c topic 把创建与切换合在一起。记录新工作之前,应检查真正活动的分支,不能因为名称已经存在,就误以为接下来的提交一定会记在那条线上。 HEAD 决定哪个名字前进 第一次提交之前,HEAD 可以指向尚未诞生的分支名,此时分支引用还无法解析为提交。这与分离状态不同:名字已被选中,只是没有首个提交对象。仓库已有提交之后,通常的附着状态下,HEAD 通过符号引用指向当前分支。创建提交时,该分支前进到新对象,其他原本共享旧末端的分支保持不动;新提交的父级关系保留祖先。分支也可能因合并或其他明确更新引用的操作而移动,并不是只有普通提交才能改变它。因此,判断某个名字为什么变化,需要检查实际发生的操作,而不只看提交按钮是否被点击。 ...

二月 5, 2027 · 2 分钟 · XB Field Notes