web-dev-qa-db-ja.com

リモートトラッキングブランチから「git fetch」と「git merge」(「git pull」など)を行う方法

Gitでいくつかのリモートトラッキングブランチを設定しましたが、「git fetch」で更新した後、それらをローカルブランチにマージすることはできません。

たとえば、「an-other-branch」というリモートブランチがあるとします。私はそれを使用して追跡ブランチとしてローカルに設定しました

git branch --track an-other-branch Origin/an-other-branch

ここまでは順調ですね。しかし、そのブランチが更新され(通常、マシンを移動してそのマシンからコミットすることにより)、元のマシンで更新したい場合、フェッチ/マージで問題が発生します:

git fetch Origin an-other-branch
git merge Origin/an-other-branch

これを行うたびに、「既に最新の」メッセージが表示され、何もマージされません。

ただし、

git pull Origin an-other-branch

常に期待どおりに更新します。

また、git diffを実行します

git diff Origin/an-other-branch

違いがあることを示しているので、構文が間違っていると思います。

私は何が間違っていますか?

EDIT [2010-04-09]:何度か確認しましたが、間違いなく別のブランチにはいません。 「git fetch」の後に「git merge」(上記を参照)を実行すると、git pullとまったく同じことが行われますか? gitステータスなどの結果を示すワークフローを取得します。

111
kaybenleroll

ブランチをフェッチするのではなく、リモート全体をフェッチします。

git fetch Origin
git merge Origin/an-other-branch
168
Gareth

ブランチを1つだけ選択する:fetch/mergevs。pull

多くの場合、「フェッチ」と「マージ」を分離することを勧められます。彼らはこれの代わりに言う:

    git pull remoteR branchB

これを行う:

    git fetch remoteR
    git merge remoteR branchB

彼らが言及していないのは、そのようなフェッチコマンドは実際にリモートレポジトリからallブランチをフェッチするということです、それはnotそのpullコマンドの動作。リモートリポジトリに数千のブランチがあるが、それらのすべてを表示したくない場合は、このあいまいなコマンドを実行できます。

    git fetch remoteR refs/heads/branchB:refs/remotes/remoteR/branchB
    git branch -a  # to verify
    git branch -t branchB remoteR/branchB

もちろん、それを覚えるのはとてつもなく難しいので、本当にすべてのブランチをフェッチしたくない場合は、ProGitで説明されているように.git/configを変更することをお勧めします。

え?

このすべての最良の説明は、ProGitの9-5章、 Git Internals-The Refspecまたはgithub経由 )にあります。 Googleで見つけるのは驚くほど難しい。

まず、いくつかの用語を明確にする必要があります。リモートブランチトラッキングの場合、通常、次の3つのブランチに注意する必要があります。

  1. リモートリポジトリ上のブランチ:refs/heads/branchB他のリポジトリ内
  2. Yourremote-tracking branchrefs/remotes/remoteR/branchB inyourリポジトリ
  3. 独自のブランチ:refs/heads/branchB insideyourrepo

リモート追跡ブランチ(refs/remotes内)は読み取り専用です。それらを直接変更しないでください。独自のブランチを変更してから、リモートリポジトリの対応するブランチにプッシュします。適切なプルまたはフェッチを行うまで、結果はrefs/remotesに反映されません。主にrefs/heads/branchB.git/configを定義するときにローカルブランチ(branch.branchB.remote = remoteR)がリモートトラッキングブランチを「追跡」すると言われているため、この区別はgitマンページから理解するのが困難でした。 。

「参照」をC++ポインターと考えてください。物理的には、SHAダイジェストを含むファイルですが、基本的にはコミットツリーへの単なるポインターです。 git fetchは多くのノードをコミットツリーに追加しますが、gitが移動するポインターを決定する方法は少し複雑です。

別の答え で述べたように、どちらも

    git pull remoteR branchB

また

    git fetch remoteR branchB

refs/remotes/branches/branchBを移動し、後者は確かにrefs/heads/branchBを移動できません。ただし、両方ともFETCH_HEADを移動します。 (.git/内のこれらのファイルのcatは、いつ変更されるかを確認できます。)git mergeは、FETCH_HEADを設定しながら、MERGE_ORIGを参照しますなど

67
cdunn2001

マージするときに、ローカルan-other-branchにいることを確認しますか?

git fetch Origin an-other-branch
git checkout an-other-branch
git merge Origin/an-other-branch

その他の説明

マージしようとしているブランチからのすべての変更は、現在使用しているブランチに既にマージされています。
具体的には、マージしようとしているブランチが現在のブランチの親であることを意味します

1回のコミットでリモートリポジトリより先に進んでいる場合、古くなっているのはリモートリポジトリであり、あなたではありません。

しかし、あなたの場合、git pullが機能する場合、それはちょうどあなたが正しいブランチにいないことを意味します。

9
VonC

Git pullは実際にはコンボツールです:git fetch(変更を取得)とgit merge(現在のコピーにマージ)を実行します

本当に正しいブランチにいるのですか?

3
RDL

これらはコマンドです:

git fetch Origin
git merge Origin/somebranch somebranch

2行目でこれを行う場合:

git merge Origin somebranch

ローカルマスターを現在のブランチにマージしようとします。

私が理解したように、質問はすでにローカルにフェッチされていて、ブランチを最新のsameブランチにマージしたいというものでした。

1
user1524957