为什么两个git工作树不能检出同一分支? [英] Why can two git worktrees not check out the same branch?

查看:151
本文介绍了为什么两个git工作树不能检出同一分支?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 致命:'mybranch'已经在'/ path / to / repo签出'

我可以看到,如果我从一个工作树登入,另一个最终会分离HEAD状态,但是那么糟糕,为什么我甚至不能检出同一个分支?

解决方案


我可以看到,如果我从一个工作树检入,另一个最终将处于分离的HEAD状态。


实际上,它不会,那就是问题所在!



每个工作树都有自己的 HEAD 和它自己的索引(又名暂存区或缓存)。全部共享实际的底层存储库以及底层分支提示文件,如 .git / refs / heads / mybranch



<那么,假设两种不同的工作树(我将它们与主要的回购分开,以便没有明显的首选)都有 HEAD 指向 mybranch ,然后从两个工作树中的一个进行提交:

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

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

  worktree1 $ cd ../worktree2 
worktree2 $ ...修改不相关的文件,而不是bar1或bar2 ...
worktree2 $ git add unrelated&& git commit -m'unrelated change'

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


$ b

现在,提交链如下所示:

  ...-- o  -  1--2 

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



提交 1 内容 c $ c>是什么在 worktree1 的索引中。它对 bar1 bar2 进行了更改。



< p 2
内容 worktree2 中索引中的内容。它在不相关中进行了更改,但它不具有文件 bar1 bar2 。实际上,您在 worktree2 中进行的提交会恢复这两个文件!



你愿意让一个或两个工作树处于分离HEAD状态,你可以通过 git checkout --detach mybranch git checkout refs / heads / mybranch 。现在至少有一个 HEAD 直接指向提交,而不是指向分支名称,Git应允许两个工作树具有相同的提交签出。


Using a separate git-worktree, why can I not check out the same branch as in the main working copy? If I try, I get the error:

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

I can see that if I check in from one worktree, the other would end up in a detached HEAD state, but is that so bad, and why can I not even check out the same branch?

解决方案

I can see that if I check in from one worktree, the other would end up in a detached HEAD state

Actually, it wouldn't, and that's the problem!

Each work-tree has its own HEAD, and its own index (aka staging-area or cache). All share the actual underlying repository, and the underlying branch tip files such as .git/refs/heads/mybranch.

Suppose, then, that two different work-trees (I'll make them both separate from the main repo just so that there's no obvious "preferred" one) both have HEAD pointing to mybranch, and you make a commit from one of the two work-trees:

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

What happens now is the usual: Git writes the index to one or more trees, writes a new commit using the new tree and whatever commit mybranch resolves to as its parent commit, and updates mybranch to point to the new commit. The index for worktree1 now matches the new commit. Now we do this:

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

What happens now is that Git writes the index ... wait, the index? Which index? Well, the index—the index in worktree2. Which does not have files modified and added from worktree1. (It does have the two bar files, unless they're totally new, but it has the old versions.) OK, so Git writes the index into one or more trees, writes a new commit using the new tree and whatever commit mybranch resolves to as its parent, and updates mybranch to point to the new commit.

The commit chain now looks like this:

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

where 1 is the commit made in ../worktree1, and 2 is the commit made in worktree2. The name mybranch, in both work-trees, points to commit 2. The name HEAD, in both work-trees, contains ref: refs/heads/mybranch. The index files in the two work trees are different, of course.

The contents for commit 1 are whatever is in the index in worktree1. It has the changes you made to bar1 and bar2.

The contents for commit 2 are whatever is in the index in worktree2. It has the changes you made in unrelated, but it does not have the changes made in files bar1 and bar2. In effect, the commit you made in worktree2 reverted the two files!

If you're willing to have one or both work-trees be in "detached HEAD" state, you can check them out that way, with git checkout --detach mybranch or git checkout refs/heads/mybranch. Now at least one of them will have HEAD pointing directly to a commit, rather than to the branch name, and Git should permit the two work-trees to have the same commit checked out.

这篇关于为什么两个git工作树不能检出同一分支?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆