2016-09-23 5 views
1

別のgit-worktreeを使用すると、メインの作業コピーと同じブランチをチェックアウトできないのはなぜですか?私がしようとすると、私はエラーを取得する:なぜ2つのgit作業ツリーは同じブランチをチェックアウトできませんか?

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

は私が1 worktreeからチェックすると、他のは切り離さHEAD状態で終わるが、それほど悪いことで、なぜ私はできないだろうと見ることができます同じブランチをチェックすることさえできますか?

答えて

5

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

実際に、それはないだろう、それが問題です!

各作業ツリーには独自のHEADとそれ自身のインデックス(別名ステージング領域またはキャッシュ)があります。全てが実際の基礎となるリポジトリと、基礎となるブランチ・ヒント・ファイル(例えば、.git/refs/heads/mybranch)を共有します。

2つの異なる作業ツリー(私はそれらを両方ともメインリポジトリから分離して明白な「優先」なものにしません)を両方ともHEADmybranchと指していて、 2つのワークツリーの一つは:今何が起こるかは通例である

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から追加されています。 (それはまったく新しいものでない限り、2つのbarファイルを持っていますが、古いバージョンです。)Gitは1つ以上のツリーにインデックスを書き込み、新しいツリーを使って新しいコミットを書き込みます。 mybranchはその親として解決され、mybranchは新しいコミットを指すように更新されます。 1../worktree1で行われたコミットされ、そして2worktree2にコミットを行っている

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

はチェーンをコミットするには次のようになります。両方の作業ツリーの中のmybranchという名前は、コミットを指す2です。どちらの作業ツリーにもHEADという名前には、ref: refs/heads/mybranchが含まれています。もちろん、2つの作業ツリーのインデックスファイルは異なります。

内容コミット1の内容は、worktree1のインデックスに含まれています。 bar1bar2に加えた変更があります。

内容コミットのために2は、worktree2のインデックスにあるものはすべてです。unrelatedに変更がありますが、にはbar1bar2の変更がありません。実際には、worktree2で行ったコミットは、の2つのファイルを元に戻しました!

一方または両方の作業ツリーを「分離HEAD」状態にしたい場合は、git checkout --detach mybranchまたはgit checkout refs/heads/mybranchでそれらをチェックアウトすることができます。今では少なくとも1人がHEADをブランチ名ではなく、コミットを直接指し示し、Gitは2つの作業ツリーにコミットをチェックアウトさせるべきです。

+0

ありがとうございます。私はgitがチェックアウトが現在のブランチコミットにはなくなっていることに気付き、デタッチされたHEAD状態のように動作すると思います。 –

+0

いいえ、分離されたHEADを取得するには、ファイル '.git/HEAD'に生ハッシュIDが必要です。これは任意のブランチ名とは無関係に発生します。つまり、HEADは記号であり、その名前が '.git/HEAD'であるブランチ上にあるか、生ハッシュIDを持っているため、そのハッシュを現在のものとしてデタッチしますコミット。 git checkout --detach mybranch'を試してみましょう。(これは主にgit checkoutで '.git/HEAD'を修正していますが、' git symbolic-ref'でも可能です) – torek

+0

時には、ブランチのきれいなチェックアウトでテストを実行したいが、何も変更しないので、分離されたHEADは問題ありません。 –

関連する問題