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

Tor*_*erg 6 git git-worktree

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

fatal: 'mybranch' is already checked out at '/path/to/repo'
Run Code Online (Sandbox Code Playgroud)

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

tor*_*rek 13

我可以看到,如果我从一个工作树登记,另一个将最终处于分离的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'
Run Code Online (Sandbox Code Playgroud)

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

worktree1$ cd ../worktree2
worktree2$ ... modify unrelated file, not bar1 or bar2 ...
worktree2$ git add unrelated && git commit -m 'unrelated change'
Run Code Online (Sandbox Code Playgroud)

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

犯链现在看起来是这样的:

...--o--1--2
Run Code Online (Sandbox Code Playgroud)

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

内容的承诺1是无论是在索引中worktree1.它拥有你所做的更改bar1bar2.

内容的承诺2是无论是在索引中worktree2.它具有您所做的更改unrelated,但它没有在文件bar1和更改中进行的更改bar2.实际上,你提交的提交worktree2 还原了两个文件!

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

  • 好的,我将尝试使用 `git checkout --detach mybranch`。有时我想在一个干净的分支结账上运行测试,我不会改变任何东西,所以一个分离的 HEAD 很好。 (2认同)