3

「master」と「testing」の2つのブランチを持つリモートのベアリポジトリがあります。HEADは「testing」を指します。このリポジトリのクローンを作成するとき、「master」と「testing」が同じリビジョンにある場合、gitは「master」をチェックアウトします(つまり、HEAD==テスト==マスター)。'testing'が1つ(または複数)のコミットの後ろまたは前にある場合にのみ、gitcloneはローカル側の'testing'ブランチをチェックアウトします。Mac OS X(10.6.8)のgit1.7.5でこれを試しました。

補遺:私は非ベアリポジトリで同じことを試しました:

mkdir A
cd A
git init
touch a
git add a
git commit -m "init repo A with a"
git checkout -b testing

ルートディレクトリに戻ります。

cd ..
git clone A B
cd B
git branch -v -a
* master                 28f599b init A
  remotes/origin/HEAD    -> origin/master
  remotes/origin/master  28f599b init A
  remotes/origin/testing 28f599b init A

それは「マスター」です!レポAに戻ります(まだブランチ「テスト中」です):

cd ../A
touch b
git add b
git commit -m "add b in branch testing"

現在、「テスト」は「マスター」の1つ先のコミットです。次に、Aのクローンを作成しましょう。

cd ..
git clone A C
cd C
git branch -a -v
* testing                23bca39 add b in branch testing
  remotes/origin/HEAD    -> origin/testing
  remotes/origin/master  28f599b init A
  remotes/origin/testing 23bca39 add b in branch testing

Aに戻り、「master」をチェックアウトして「testing」とマージすることで、この奇妙な動作を再確認できます(すべてのブランチが同じヘッドを持つように)。これで、クローンAがDになり、Dがマスターでチェックアウトされます。

4

2 に答える 2

1

git cloneすべてのブランチとその履歴、およびSHA1をコピーし、ヘッドの参照はコピーしません。AFAIK refspecsは、クローン作成よりもgitの方が新しいため(明らかに)転送されず、クローンプロトコルはそれらを保持しません...これは推測することを意味します(編集:これはメーリングリストによって確認されています)。

頭の参照は、そのSHA1を照合することにより、クローン中に推測されます。あなたの場合、SHA1はあいまいです。なぜならmastertesting両方が一致するためmaster、慣例により選択されるからです。これは私の知る限りどこにも文書化されていませんが、文書化されているはずです。

これが正しいことを確認するには、Bサンプルリポジトリに移動してを実行しますgit ls-remote。出力は、refではなくSHA1を提供します。

1c3eebcd1bd3659a40f02880918d5fbd5614b51a    HEAD
1c3eebcd1bd3659a40f02880918d5fbd5614b51a    refs/heads/master
1c3eebcd1bd3659a40f02880918d5fbd5614b51a    refs/heads/testing

回避策として、

git clone -b <branch_name>

masterやtestなどの目的のブランチbranch_nameのクローンを作成してチェックアウトします。

現時点では、HEADがマスターであり、マスターがチェックアウトのデフォルトブランチであるという規則に固執する必要があると思います。開発者がクローンを作成するために別のヘッドを使用するように設定されている場合は、-bスイッチを使用します。

于 2011-08-03T14:22:53.443 に答える
0

gitメーリングリストから回答を得ました-@Shelhamer:その通りです

はい、これは既知の問題です。

gitプロトコルは、参照のリストとそれらが指すオブジェクトを送信するだけです。したがって、ローカルクローンは、HEADが指している参照を推測するように強制されます。たとえば、次のようなものがあります。

28f599b ... HEAD 1234abc ... refs / heads / master 28f599b ... refs / heads / tests

HEADがおそらく「テスト中」であることがわかります。しかし、それが見られる場合:

28f599b...ヘッド28f599b...参照/ヘッド/マスター28f599b...参照/ヘッド/テスト

次に、任意に1つを選択する必要があります。現在のヒューリスティックは、他のヒューリスティックよりも「マスター」を優先することです。それ以外の場合は、アルファベット順に最初に選択します。したがって、少なくとも決定論的ですが、お気づきのように、常に正しいとは限りません。

これに対する実際の解決策は、gitプロトコルを拡張して、シンボリックref情報を伝達することです(次に、クライアントとサーバーの両方がアップグレードされるのを待ちます)。過去にいくつかのパッチがフロートされましたが、何も起こりませんでした。多分それはそれらを復活させる時です。

回避策として、「テスト」が必要なものであることが事前にわかっている場合は、「gitclone-btesting...」を使用できます。

見る:

1. http://thread.gmane.org/gmane.comp.version-control.git/102039

2. http://article.gmane.org/gmane.comp.version-control.git/113567

于 2011-08-04T13:32:42.493 に答える