为什么两个git工作树不能检查同一个分支?

时间:2016-09-23 16:32:04

标签: git git-worktree

使用单独的git-worktree,为什么我不能检查与主工作副本中相同的分支?如果我尝试,我会收到错误:

fatal: 'mybranch' is already checked out at '/path/to/repo'

我可以看到,如果我从一个工作树上签入,另一个最终将处于一个独立的HEAD状态,但是那个很糟糕,为什么我甚至不能查看同一个分支?

1 个答案:

答案 0 :(得分:12)

  

我可以看到,如果我从一个工作树登记,另一个最终会处于分离的HEAD状态

实际上,不会,这就是问题!

每个工作树都有自己的HEAD和自己的索引(也就是临时区域或缓存)。所有人共享实际的底层存储库,以及基础分支提示文件,例如.git/refs/heads/mybranch

然后,假设两个不同的工作树(我将它们都与主要仓库分开以便没有明显的“首选”)都HEAD指向mybranch ,并从两个工作树中的一个提交:

repo$ cd ../worktree1
worktree1$ ... hack away ...
worktree1$ git add bar1 bar2 && git commit -m 'foo some bars'

现在发生的情况通常是:Git将索引写入一个或多个树,使用新树写入新提交,并将任何提交mybranch解析为其父提交,并更新mybranch指向新提交。 worktree1的索引现在与新提交匹配。现在我们这样做:

worktree1$ cd ../worktree2
worktree2$ ... modify unrelated file, not bar1 or bar2 ...
worktree2$ git add unrelated && git commit -m 'unrelated change'

现在发生的事情是Git编写索引...等待, 索引? 哪个指数?那么, 索引 - worktree2中的索引。哪个文件没有从worktree1修改和添加。 (它确实有两个bar文件,除非它们是全新的,但它有旧版本。)好的,所以Git将索引写入一个或多个树,写一个使用新树的新提交和任何提交mybranch解析为其父级,并更新mybranch以指向新提交。

提交链现在看起来像这样:

...--o--1--2

其中1../worktree1中的提交,而2worktree2中的提交。两个工作树中的名称mybranch都指向提交2。两个工作树中的名称HEAD包含ref: refs/heads/mybranch。当然,两个工作树中的索引文件是不同的。

提交1内容worktree1中索引中的内容。它包含您对bar1bar2所做的更改。

提交2内容worktree2中索引中的内容。它包含您在unrelated中所做的更改,但没有在文件bar1bar2中进行了更改。实际上,您在worktree2 中提交的提交已恢复这两个文件!

如果您愿意让一个或两个工作树处于“分离的HEAD”状态,您可以使用git checkout --detach mybranchgit checkout refs/heads/mybranch以这种方式检查它们。现在,其中至少有一个将HEAD直接指向提交,而不是指向分支名称,Git应该允许两个工作树签出相同的提交