web-dev-qa-db-ja.com

git fetchとgit fetch Originマスターは、ブランチの追跡に異なる影響を与えます

これは主にGitに精通しようとしている好奇心の性質です。 「git fetch」のドキュメントを見てきましたが、以下の説明がわかりません。事前に感謝し、これが非常に明白な場合は謝罪します。

1)GitHubなどの中央リポジトリから、2つのマシンwebsiteHostAのそれぞれにHostBという名前のリポジトリを複製します。

2)HostAで、_README.txt_と言うファイルに変更を加えてコミットします。
HostAのこの時点で、ブランチmasterと_Origin/master_のコミットは、まだプッシュしていないので、予想どおり異なります

_git show master
git show Origin/master
_

異なるハッシュを報告する(masterには変更があり、_Origin/master_にはないため)

3)プッシュしたら、その後も同じです。


4)ここで、HostBについて、次の操作を行った場合:

_git fetch
git merge FETCH_HEAD
_

その後、HostBでmasterおよび_Origin/master_は、_git show_で照会されたときに同じハッシュを報告します

だが

代わりにHostBで行った場合:

_git fetch Origin master
git merge FETCH_HEAD
_

その時点でハッシュはまだ異なります。

_git show Origin
git show Origin/master
_

レポート異なるハッシュ

追跡ブランチ_Origin/master_は、プレーンな_git fetch_を実行するまで更新されません。

どうしてこれなの?

22
Xoanon93

ブランチに関連する リモート追跡ブランチ がある場合、その構成は次のようになります。

git config branch.[branch-name].remote [remote-name]
git config branch.[branch-name].merge [remote-master]

git fetchの2つのコマンドの違いを説明する重要な部分は次のとおりです。

<refspec>

<refspec>パラメーターの形式は、オプションで、+に加えて、ソース参照<src>、コロン:、宛先参照<dst>の順になります。
<src>に一致するリモートrefがフェッチされ、<dst>が空の文字列でない場合、それに一致するローカルrefは<src>を使用して早送りされます。

繰り返しましょう。

<dst>が空の文字列でない場合、それに一致するローカル参照は<src>を使用して早送りされます。
知っています:

  • git fetchgit fetch Origin master:master(ブランチ設定のデフォルト値から)と同等であるため、リモート追跡ブランチを更新します:refspecの宛先はあなたのために指定されます

  • git fetch Origin masterは「git fetch Origin master:」ではなく「git fetch Origin master:master」と同等です。 'master'ブランチまたはリモートトラッキング 'FETCH_HEAD'ブランチではなく、remotes/Origin/masterに(リモート 'Origin'の) 'master'ブランチのフェッチ値を格納します( from JakubNarębski 's answer
    つまり、refspecの宛先を指定しなかった

23
VonC

答えは、git fetchから返されるメッセージにあります。最初のケースでは、refspecを指定せずにフェッチすると、リモートトラッキングブランチが更新されていることがわかります。

remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /depot
   c67d1c8..1941673  master     -> Origin/master

Origin/masterがOriginのマスターで更新されたことをメッセージが伝える方法に注意してください。

Refspecを指定する2番目のケースでは、まったく異なる結果が得られます。

remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /depot
 * branch            master     -> FETCH_HEAD

したがって、refspecを指定すると、リモート追跡ブランチ(Origin/master)は更新されず、FETCH_HEADのみが更新されます。

最終的な結果は、あなたが本当にそうでないときでも、Origin/masterの先を行っているように見えることです。この動作が望ましい理由を想像することはできませんが、それは間違いなくフェッチコマンドの興味深い小さな癖です。

0
Ethan Brown

自分で早送りしたい場合、またはgit pullを使用します。 git fetchの目的は作業ツリーを更新することではないことを理解していないようです。フェッチは、追跡ブランチを更新することを目的としています。

0
UpAndAdam