「git pull」と「git fetch」の違いは何ですか?


11917

違いは何ですかgit pullとはgit fetch


364
私はgitのおよそこのよく書かれた記事はそれの価値が読書を取得し、gitのプルが見つかりました:longair.net/blog/2009/04/16/git-fetch-and-merge
マルコス・オリヴェイラ

51
私たちの代替アプローチはgit fetch; git reset --hard origin/master、私たちのワークフローの一部となっています。それはローカルの変更を吹き飛ばし、マスターで最新の状態に保ちますが、現在の変更の上に新しい変更を追加して混乱させるだけではありません。しばらく使ってみましたが、基本的には実際にはずっと安全だと感じています。まず、進行中の作業を必ず追加/コミット/隠しておいてください!
Michael Durrant 2014年

26
git stashを正しく使用する方法を知っていることを確認してください。「プル」と「フェッチ」について質問している場合、おそらく「
スタッシュ

36
Mercurialから来た多くの人々は "git pull"を使い続けています。それは "hg pull"と同等だと思っています。それはそうではありません。「hg pull」に相当するGitは「git fetch」です。
セルジュシュルツ2015年

8
ブランチに更新されたコードをフェッチする命令をフェッチGITし、また、あなたの地元、gitのプルコマンドは、現在のブランチの唯一の更新されたコードをフェッチして、新しく追加された枝を取得します
Kartikパテル

回答:


9918

最も単純な用語でgit pullは、のgit fetch後にが続きgit mergeます。

あなたは行うことができますgit fetch下のリモート追跡ブランチを更新するために、いつでもrefs/remotes/<remote>/

この操作はrefs/heads、の下にある独自のローカルブランチを変更することはなく、作業コピーを変更しなくても安全です。私はgit fetch、バックグラウンドでcronジョブで定期的に実行されている人々についてさえ聞いたことがあります(ただし、これを行うことはお勧めしませんが)。

A git pullは、ローカルブランチをリモートバージョンで最新の状態にし、他のリモート追跡ブランチを更新するために行うことです。

Gitドキュメント– git pull

デフォルトモードでgit pullは、はのgit fetch後に続く省略形ですgit merge FETCH_HEAD


326
「「git pull」は、リポジトリを最新の状態にするために行うことです」<-リポジトリの更新は、fetchによってすでに行われていませんか?それはあなたのローカルブランチをリモートブランチで最新のものにするという意味ですか?マージする:リモートブランチとそれらのブランチのローカルコピーをマージしますか、またはここで正確に何をマージしますか?
アルバート、

194
@アルバート:ええ、奇妙な言葉遣いです。 git pull常に現在のブランチにマージされます。だから、あなたが引くしたい支店を選択から、それが現在のブランチにそれを引っ張ります。以下からの分岐は、ローカルまたはリモートことができます。登録されていないリモートブランチにすることもできgit remoteます(つまり、git pullコマンドラインでURLを渡します)。
2010

129
@espertus:いいえ。プッシュで自動的にマージが行われることはありません。ユーザーは、ローカルで任意のマージの競合を解決、プルに期待され、その後、リモートにプッシュバック。
グレッグ・ヒューギル

33
私が午前た場合/home/alice/とやるgit fetch /home/bob、私はそれ以降にどのようなパラメータを渡す必要がありますかgit merge
ripper234 2011年

106
Gitを学習している人への注意:プラスaでpull実際にエミュレートすることはできません。私は、リモートブランチポインターのみが変更される変更をフェッチしましたが、何もしません。一方、私の追跡ブランチを早送りします。fetchmergemergepull
ロマン・スターコフ2012

2172
  • を使用するとpull、Gitは自動的に作業を実行しようとします。状況依存であるため、Gitはプルされたコミットを現在作業中のブランチに pull マージします最初に確認することなく、コミットを自動的にマージします。ブランチを厳密に管理しないと、頻繁に競合する可能性があります。

  • するとfetch、Gitは現在のブランチに存在しないターゲットブランチからのコミットを収集し、ローカルリポジトリに保存します。ただし、現在のブランチとはマージされません。これは、リポジトリを最新の状態に保つ必要があるが、ファイルを更新すると壊れる可能性のある問題に取り組んでいる場合に特に便利です。コミットをマスターブランチに統合するには、を使用しますmerge


34
同意、素晴らしいコメント。だから私はgit pullが嫌いです。リビジョンツールにコードの編集を許可するのが適切な場合はいつですか。そして、それは2つのファイルをマージすることで何をしているのではないですか?これらの2つの編集がファイル内で物理的に分離されているが、論理的に矛盾している場合はどうなりますか?
リーディクソン

126
@elexhobby略してgit fetch.git/ディレクトリ(別名:ローカルリポジトリ)のみを更新し、外部.git/(別名:作業ツリー)は更新しません。それはあなたのローカルブランチを変更せず、また触れませんmaster。それは触れremotes/origin/masterます(を参照git branch -avv)。さらにリモコンがある場合は、を試してくださいgit remote update。これは、git fetch1つのコマンドでのすべてのリモート用です。
Tino 2013

24
@Tinoあなたのものは本当に最も重要なポイントです。「リモート」ブランチが実際にはのハッシュの束として保存されていることを人々は知らないかもしれません.git/refs/remotes/origin/
クリス

13
フェッチすると、Gitは現在のブランチに存在しないターゲットブランチからのコミットを収集し、ローカルリポジトリに保存します。リモートから何がもたらされたかを確認し、ローカルブランチにマージするにはどうすればよいですか?
アレックス

13
@Tino私がまだ理解していないのは...要点は何ですか?更新のみの場合にフェッチを使用するのはなぜ.gitですか?意図された利点は何ですか、その後私は何をすべきですか?
BadHorsie 2016年

1210

gitの設計哲学とSVNのようなより伝統的なソース管理ツールの哲学を対比することが重要です。

Subversionは、クライアント/サーバーモデルで設計および構築されました。サーバーである単一のリポジトリーがあり、複数のクライアントがサーバーからコードをフェッチして作業し、サーバーにコミットすることができます。操作を実行する必要がある場合、クライアントは常にサーバーに接続できると想定されています。

Gitは、中央リポジトリーを必要とせずに、より分散されたモデルをサポートするように設計されました(ただし、希望する場合は確かに使用できます)。また、gitは、クライアントと「サーバー」が同時にオンラインである必要がないように設計されました。Gitは、信頼性の低いリンクを使用しているユーザーでも、電子メールでコードを交換できるように設計されています。完全に切断された状態で作業し、CDを書き込んでgit経由でコードを交換することができます。

このモデルをサポートするために、gitはコードを含むローカルリポジトリと、リモートリポジトリの状態を反映する追加のローカルリポジトリを維持します。リモートリポジトリのコピーをローカルに保持することにより、gitはリモートリポジトリにアクセスできない場合でも必要な変更を把握できます。後で変更を他の誰かに送信する必要がある場合、gitはそれらを一連の変更としてリモートリポジトリで認識されている特定の時点から転送できます。

  • git fetch 「リモートリポジトリのローカルコピーを最新の状態にする」というコマンドです。

  • git pull 「リモートリポジトリの変更を、自分のコードを保持する場所に持っていきます。」

通常、git pullこれを行うには、a git fetchを実行してリモートリポジトリのローカルコピーを最新の状態にし、変更内容を独自のコードリポジトリと作業コピーにマージします。

重要なのは、ワークステーションにはプロジェクトのコピーが少なくとも3つあることが多いことを覚えておいてください。1つのコピーは、独自のコミット履歴を持つ独自のリポジトリです。2番目のコピーは、編集および構築する作業コピーです。3番目のコピーは、リモートリポジトリのローカルの「キャッシュされた」コピーです。


75
技術的には、ローカルリポジトリとリモートリポジトリは実際にはまったく同じです。Gitでは、リポジトリは親を指すコミットのDAGです。ブランチは、技術的には意味のあるコミット名にすぎません。ローカルブランチとリモートブランチの唯一の違いは、リモートブランチには最初remoteName/ からGitがプレフィックスとして付けられていることです。Gitがどのように機能するかを理解したら(そしてそれは美しくシンプルで、本当に)、すべてが理にかなっています。
Emil Lundberg 2013

13
説明ありがとうございます。私は今まで、Gitが設計されていて、中央リポジトリーを持つ必要がないことを本当に理解していませんでした。誰もがGitを説明するときは常に「DVCS」と言いますが、比較的新しいプログラマーとして、それは私には何の意味もありません。私はCVCSをたことがありません。また、他の人(つまりGithub)と共同作業するときに中央のリモートリポジトリを操作したこともありません。
ブライアンピーターソン

7
それで、これに基づいて、cronジョブでgit-fetchするのがなぜISNではないのですか?作業しているリモートのコピーを常にローカルマシンに保持することは、良い考えのようです。実際、私は、過去24時間にリモートを更新したかどうかを確認し、インターネット接続用のudevフックとリンクするスクリプトを作成したいと思っています。
ブライアンピーターソン

24
cronジョブを作成するのが適切ではない理由の1つは、新しいチケットやブランチの更新を処理するときに、変更がフェッチされるのを確認することです。フェッチ中に変更が反映されない場合は、同僚のプログラマーに「ねえ、あなたはプッシュしましたか?」と尋ねる方が自信があります。最後にフェッチしてから、リポジトリ内の「チャーン」の量もわかります。これは、このリポジトリに対して現在行われている変更の量と速度を理解するのにも役立ちます。
Michael Durrant 14

5
@Nabheet Thingは、Gitがコンテンツ指向であることです。データは1回だけ保存され、複数回ポイントされます。そのため、Gitでは、ほとんどのオブジェクトが同じであるため、オリジナルの上に複数のコミットを行っても、リポジトリのサイズに大きな影響はありません。
cst1992

890

ここにあるすべてはそれをすべて一緒にどのように適合するかのオリバースティールの画像は

ここに画像の説明を入力してください

十分な関心があれば、画像を更新して追加しgit cloneたり、git merge...


156
で画像を更新git cloneし、git merge非常に参考になります!
MEMark

20
はい、追加してくださいgit merge- はリモートからのみマージされ、リモートブランチからプルされているリモートブランチを追跡しているローカルブランチのローカルコミットを無視するためmerge、個別に呼び出された場合は呼び出しと同じではないことを明確に示す必要があります。pullpull
JustAMartin 2015年

12
写真は千の言葉に値する!クローンとマージのデータフローで更新されたイメージはどこかに準備ができていますか?すでに図にあるもの以外のデータフローはありますか?
Shikhanshu 2015年

10
@Contangoはクローンを追加してマージしてください。私のような初心者に役立つでしょう。
2016年

11
th3slyとthedarkpassengerによる他の回答(下記)のクローンとマージを示す2つの図があります。
intotecho

488

の使用例の1つgit fetchは、最後のプル以降のリモートブランチの変更を次のように伝えます...実際のプルを行う前に確認できるため、現在のブランチと作業コピーのファイルが変更される可能性があります。

git fetch
git diff ...origin

参照:diffコマンドのダブルドットおよびトリプルドット構文については、https//git-scm.com/docs/git-diff


9
なんでgit diff ..origin
エリックカプルン

3
git diff originとgit diff ..originは機能しているように見えますが、この奇妙なものは機能しません...もの
Marc

19
@Compustretchスペースは想定されていませんでした。 git diff ...originとは異なりますgit diff $(git-merge-base HEAD origin) originkernel.org/pub/software/scm/git/docs/git-diff.html#_descriptiongit diff [--options] <commit>...<commit> [--] [<path>…]セクションを参照)。は概念的には、現在のブランチがから分岐した後に行われた変更であり、現在のブランチがから分岐した後に行われた変更の逆も含まれます。git diff origingit diff ...originoriginorigingit diff originorigin
Max Nanasy 2013

2
..コマンドはどれも(Windowsでは)私には機能しませんでしたが、git diff origin/master以下のように機能します
Brian Burns 14

OSXでgit 2.0.0を使用する場合も同じです。これらのコマンドはどれも機能しませんでした。それらは廃止されましたか?
K.-Michael Aye 2014年

373

何が違うのかを理解するのに少し時間がかかりましたが、これは簡単な説明です。masterローカルホストにはブランチがあります。

リポジトリを複製すると、リポジトリ全体がローカルホストにフェッチされます。これは、その時点でHEAD、同じを指すオリジン/マスターポインターとマスターが存在することを意味しますHEAD

作業を開始してコミットを行うときは、マスターポインターをHEAD+ コミットに進めます。しかし、オリジン/マスターポインターは、クローンを作成したときの状態をまだ指しています。

したがって、違いは次のようになります。

  • 実行するgit fetchと、リモートリポジトリ(GitHub)内のすべての変更がフェッチさ、オリジン/マスターポインターがに移動しHEADます。その間、あなたのローカルブランチマスターはそれがどこにあるかを指し示し続けます。
  • を実行するとgit pull、基本的にフェッチ(前述のとおり)が行われ、新しい変更がマスターブランチにマージされ、ポインターがに移動しますHEAD

14
origin / masterは、origin上のmasterのCOPYであるローカルブランチです。フェッチすると、local:/ origin / masterが更新されます。gitのすべてがブランチであることを本当に理解したら、これは非常に理にかなっており、さまざまなチェンジセットを維持し、迅速なローカルブランチを作成し、マージしてリベースし、一般的に安価なブランチから多くの価値を引き出す非常に強力な方法です。モデル。
cam8001 2013年

3
まだ混乱しています。私は思ったgit fetch、文字通りあなたのローカルリポジトリにリモートリポジトリ上の変更をダウンロードすることでしたが、それらをコミットしないで-すなわち、彼らはまだあなたの地元のレポにコミット/追加する必要があります。
krb686 2015

3
fetchは、リモート/オリジン(github)からローカルオリジンにのみプルします。ただし、実際の作業ファイルにはマージされません。プルすると、フェッチされ、現在の作業ファイルにマージされます
ヘラルド

223

時には視覚的な表現が役立ちます。

ここに画像の説明を入力してください


18
この写真は、ローカルリポジトリにも影響を与えることを示していると思います。つまり、Gitプルはローカルリポジトリと作業コピーに影響を与える組み合わせです。現時点では、作業コピーに影響するだけのようです。
非極性2016

10
@太極者無極而生同意-この画像はフェッチをスキップしているように見えるため、かなり誤解を招くものgit pullですが、これはもちろん不正確です。
forresthopkinsa

9
「ローカルリポジトリ」と「作業コピー」の違いは何ですか?それらは両方ともコンピューター上でローカルではありませんか?
theITvideos

1
では、git fetchの使用は何ですか?ローカルリポジトリと作業コピーにどのような違いがあるかを確認するにはどうすればよいですか?
Vikash

2
@theITvideosいいえ、違います。ローカルリポジトリは、をコミットしたときに(作業リポジトリから)コードが移動する場所です。(プッシュするとリモートリポジトリに移動します)。
Vikash

219

簡単に

git fetchと似てpullいますが、マージされません。つまり、リモート更新(refsおよびobjects)をフェッチしますが、ローカルは同じままです(つまりorigin/master、更新されmasterますが、同じままです)。

git pull リモートからプルダウンし、即座にマージします。

もっと

git clone レポを複製します。

git rebase現在のブランチから上流のブランチにないものを一時的な領域に保存します。これで、ブランチは変更を始める前と同じになります。したがって、git pull -rebaseリモートの変更をプルダウンし、ローカルブランチを巻き戻し、最新の状態になるまで現在のブランチの上から1つずつ変更を再生します。

また、git branch -aローカルとリモートのすべてのブランチで何が起こっているかを正確に示します。

このブログ投稿は役に立ちました:

git pull、git fetch、git clone(およびgit rebase)の違い-Mike Pearce

そしてカバーgit pullgit fetchgit clonegit rebase

====

更新

これを実際にどのように実際に使用するかを示すためにこれを更新すると思いました。

  1. リモートからローカルリポジトリを更新します(ただし、マージしないでください)。

    git fetch 
    
  2. アップデートをダウンロードしたら、違いを見てみましょう:

    git diff master origin/master 
    
  3. これらの更新に満足している場合は、マージします。

    git pull
    

ノート:

ステップ2:ローカルとリモートの差分の詳細については、ローカルgitブランチとリモートブランチを比較する方法を参照してください

ステップ3:git rebase originここで行う方が、おそらくより正確です(たとえば、変化の速いリポジトリでは)。別の回答で@Justin Ohmsのコメントを参照してください。

参照:http : //longair.net/blog/2009/04/16/git-fetch-and-merge/


1
ローカルコードに "ヒント"を反映させたいだけの場合は、を使用する必要があるように思えますgit clone。ヒントは引用符で囲みます。これは、マスターが何であれ、誰かがgithub.comから「zipとしてダウンロード」することを意味すると思います
Chris K

3
git fetchした後の変更に満足できない場合はどうなりますか?次はどうする?
クグツメン2015年

リベースに関するあなたのパラグラフは私が探していたものでした。すべてをゼロにして、リモートから更新し、作業中に発生した以前のコミットの上に変更を再生することに関する全体的なアイデア。それが正しいと仮定して完璧な説明。;)
coblr 2016

178
git-pull-別のリポジトリまたはローカルブランチからフェッチしてマージする
あらすじ

git pull…
説明

指定されたパラメーターでgit-fetchを実行し、git-mergeを呼び出して 
現在のブランチにヘッドを取得しました。--rebaseを使用して、git-rebaseを呼び出します
git-mergeの代わりに。

を使用できることに注意してください。(現在のディレクトリ)プルする<リポジトリ>として
ローカルリポジトリから-これはローカルブランチをマージするときに役立ちます 
現在のブランチに。

また、git-pull自体と基礎となるgit-mergeを対象としたオプションもあることに注意してください。 
git-fetch用のオプションの前に指定する必要があります。

履歴をマージしたい場合はプルします。この周りの記事にタグを付けている人がいるので、「codezが欲しい」場合はフェッチします。


5
非常に興味深いですが、「コードのみ」が必要なユースケースは実際にはわかりません。フェッチするとコードはどうなりますか?消されましたか?リモートが変更されるとどうなりますか?マージしない場合、コードを消去せずにリポジトリにどのように入るのですか?
e-satis

11
@ e-satis:リモートブランチもローカルでマシンに保存されます。そのgit fetchため、リポジトリから変更をフェッチし、ローカルのリモートブランチを更新します。ローカルリモートブランチを追跡するローカルブランチには影響しないため、作業コピーには影響しません。これで、aを実行するmergeと、フェッチされた変更がローカルブランチにマージされます。
jeffreyveon、2011年

fetchコマンドの簡単な使用例:以前にフェッチを使用してダウンロードしたため、ネットワーク接続の要件なしで最新のローカルリポジトリのみにアクセスし、マージやコードレビューなど、他の人の最近のコミットを含む時間のかかる操作を実行します。必要なものすべて(たとえば、他の開発者を訪問して他のリポジトリのネットワークに接続しているとき)。pullコマンドは同じコミットをダウンロードしますが、実行するマージは望ましくない場合があります。
Lorenzo Gatti 2013

163

リモートリポジトリからフェッチし、違いを確認してから、プルまたはマージできます。

これは、リモートリポジトリと呼ばれるoriginブランチとmaster、リモートブランチの追跡と呼ばれるブランチの例ですorigin/master

git checkout master                                                  
git fetch                                        
git diff origin/master
git rebase origin master

35
おそらく変更をすでにフェッチしているので、プルをスキップして、最後のステップとして「git rebase origin」を実行するだけです。その理由は、フェッチを行ってからの時間に誰かが変更をプッシュした可能性があり、これらは差分レビューを行ったフェッチに含まれていなかったからです。
ジャスティンオーム

158

短くて簡単な答えは、git pull単純にがgit fetch続くことgit mergeです。

が好きかどうかに関わらず自動的にマージされるgit pullことに注意することは非常に重要です。もちろん、これによりマージの競合が発生する可能性があります。あなたのリモコンがoriginで、ブランチがだとしましょうmastergit diff origin/masterプルする前であれば、マージの競合の可能性についてある程度の知識が必要であり、それに応じてローカルブランチを準備できます。

プルとプッシュに加えて、次のようなワークフローが含まgit rebaseれます。これは、リンクされた記事から言い換えます。

git pull origin master
git checkout foo-branch
git rebase master
git push origin foo-branch

このような状況に陥った場合、誘惑に駆られる可能性がありますgit pull --rebase。あなたが本当に、本当にあなたが何をしているかを知らない限り、私はそれに対して助言します。この警告は、バージョンのmanページからのものです:git-pull2.3.5

これは潜在的に危険な操作モードです。それは歴史を書き直しますが、あなたがすでにその歴史を発表したとき、それは良い前兆ではありません。git-rebase(1)を注意深く読んでいない限り、このオプションを使用しないでください。


2
@JustinOhms git pull --rebase与えられた状況で正しくない場合、2つのステップで行われる場合は正しいですか?それが正しいことである場合、2つのステップでそれを行うことの追加の利点は何ですか?
Kaz 2013年

@Kaz-リベースは自動ではないため。最初に変更をフェッチすると、判断を下すことができます。既にプッシュした履歴のリベースに関する問題は修正されません。これにより、まだプッシュしていない変更をリベースしても安全かどうかを確認できます。
ジャスティンオームズ2013年

2
@JustinOhms変更をリベースしても安全かどうかをどのように判断しますか?私はgit rebaseを試してみて、混乱した場合はバックトラックします。その場合、git pull --rebaseを実行することもできます。しかし、おそらく他の方法がありますか?
Kaz 2013年

3
@KaZ gitkを使用すると、ブランチの構造を視覚的に確認できます。ローカルヘッド、リモート、ブランチ構造の位置を、フェッチしたものとの関係で表示します。このようにして、リモートにプッシュしたものより前の祖先に基づいてフェッチされた変更をリベースしないようにすることができます。
ジャスティンオームス2013年

rebaseまだプッシュされていないローカルブランチで作業しているときに使用します。リモートに存在するブランチで作業している場合、rebase厄介な問題が発生する可能性があるため、通常のを使用することをお勧めしますmerge
Justus Romijn、2014

151

OK、ここに関するいくつかの情報があるgit pullgit fetch、あなたは、いくつかの簡単な言葉で、実際の違いを...理解できるように、フェッチ最新のデータを取得しますが、いないコードの変更とあなたの現在のローカル支店コードを台無しにするつもりはないが、プル GETコードが変更され、ローカルブランチにマージされます。それぞれについての詳細を取得するには、以下を読んでください。

git fetch

すべての参照オブジェクト、および新しいブランチをローカルリポジトリにダウンロードします...

1つ以上の他のリポジトリからブランチやタグ(まとめて「refs」)を、それらの履歴を完成するために必要なオブジェクトとともにフェッチします。リモート追跡ブランチが更新されました(この動作を制御する方法については、以下の説明を参照してください)。

デフォルトでは、フェッチされている履歴を指すタグもすべてフェッチされます。その効果は、関心のあるブランチを指すタグをフェッチすることです。このデフォルトの動作は、-tagsまたは--no-tagsオプションを使用するか、remote..tagOptを構成することで変更できます。タグを明示的にフェッチするrefspecを使用することで、関心のあるブランチを指さないタグもフェッチできます。

git fetchは、指定されたリモートが存在する場合、単一の名前付きリポジトリまたはURL、または一度に複数のリポジトリからフェッチできます。構成ファイルのエントリ。(git-config 1を参照)。

リモートが指定されていない場合、現在のブランチに設定されたアップストリームブランチがない限り、デフォルトで元のリモートが使用されます。

フェッチされた参照の名前は、参照先のオブジェクト名とともに、.git / FETCH_HEADに書き込まれます。この情報は、スクリプトや他のgitコマンド(git-pullなど)で使用される場合があります。


git pull

リモートからローカルの現在のブランチへの変更を適用します...

リモートリポジトリからの変更を現在のブランチに組み込みます。デフォルトモードでは、git pullはgit fetchの後にgit merge FETCH_HEADが続く形式です。

より正確には、git pullは指定されたパラメーターでgit fetchを実行し、git mergeを呼び出して、取得したブランチヘッドを現在のブランチにマージします。--rebaseを使用すると、git mergeではなくgit rebaseが実行されます。

git-fetch 1に渡されるリモートリポジトリの名前である必要があります。任意のリモート参照(たとえば、タグの名前)または対応するリモート追跡ブランチを持つ参照のコレクション(たとえば、refs / heads / :refs / remotes / origin /)に名前を付けることができますが、通常は名前ですリモートリポジトリのブランチの。

およびのデフォルト値は、git-branch --trackで設定された現在のブランチの「リモート」および「マージ」構成から読み取られます。


以下のビジュアルも作成して、一緒に作業する方法git fetchgit pull作業方法を示します...

git pullとgit fetch


10
画像が気に入ったら、すべてのgitコマンドと同じようなgitチートシートを確認してください... ndpsoftware.com/git-cheatsheet.html
Tom

3
クローンはローカルリポジトリにも影響しませんか(リモートからすべての履歴をコピーします)。
トムロレド

135

ここに画像の説明を入力してください

このインタラクティブなグラフィック表現は、gitの理解に非常に役立ちます。http//ndpsoftware.com/git-cheatsheet.html

git fetchリモートからローカルリポジトリに変更を「ダウンロード」するだけです。git pull変更をダウンロードし、現在のブランチにマージします。「デフォルトのモードでgit pullは、がgit fetch後に続く場合の省略形ですgit merge FETCH_HEAD。」


18
人々は、リンクをクリックしてさまざまな列を操作します。このチートシートは、各コマンドの違いを完全に理解するために私が見た中で最高のリソースです。
M.ルイサカリオン

この回答はトップに
戻る

126

ボーナス:

上記の回答のプル&フェッチと言えば、興味深いトリックを共有したいと思います。

git pull --rebase

この上記のコマンドは、私のgitライフで最も便利なコマンドであり、多くの時間を節約しました。

新しいコミットをサーバーにプッシュする前に、このコマンドを実行すると、最新のサーバー変更が自動的に同期され(フェッチ+マージを使用)、コミットがgitログの一番上に配置されます。手動のプル/マージについて心配する必要はありません。

詳細はhttp://gitolite.com/git-pull--rebase


4
いいヒントですが、リベースをコミットすることでコミットハッシュを変更することを新しいgitユーザーに言及することは価値があります(subversionからの意外な発見です)。
AlexMA 2016

1
あなたは間違いが何であるかを説明できますgit pullgit pull --rebase
シャイユット

2
上記の回答でこのメソッドに関する

118

私はこれらの事柄を把握するために状況を視覚的に表現するのが好きです。たぶん他の開発者もそれを見てみたいので、ここに私の追加があります。すべてが正しいかどうかはわかりませんので、間違いがあればコメントしてください。

                                         LOCAL SYSTEM
                  . =====================================================    
================= . =================  ===================  =============
REMOTE REPOSITORY . REMOTE REPOSITORY  LOCAL REPOSITORY     WORKING COPY
(ORIGIN)          . (CACHED)           
for example,      . mirror of the      
a github repo.    . remote repo
Can also be       .
multiple repo's   .
                  .
                  .
FETCH  *------------------>*
Your local cache of the remote is updated with the origin (or multiple
external sources, that is git's distributed nature)
                  .
PULL   *-------------------------------------------------------->*
changes are merged directly into your local copy. when conflicts occur, 
you are asked for decisions.
                  .
COMMIT            .                             *<---------------*
When coming from, for example, subversion, you might think that a commit
will update the origin. In git, a commit is only done to your local repo.
                  .
PUSH   *<---------------------------------------*
Synchronizes your changes back into the origin.

リモートのフェッチされたミラーを持つことのいくつかの主な利点は次のとおりです。

  • パフォーマンス(ネットワーク経由で絞り込まずに、すべてのコミットとメッセージをスクロールします)
  • ローカルリポジトリの状態に関するフィードバック(たとえば、AtlassianのSourceTreeを使用します。これにより、オリジンと比較してコミットが進んでいるか遅れているかを示す電球が表示されます。この情報はGIT FETCHで更新できます)。

git pullaはマージも実行しませんか?つまり、作業コピーまで行きますか?
カミエルワンルーイ2014年

良い点です。そうすれば、すべての変更が作業コピーに反映され、ローカルリポジトリにコミットできます。ビジュアルを更新します。
Justus Romijn 14年

@JustusRomijnプルはローカルリポジトリも更新しませんか?元のコピーと作業コピーのアスタリスクの間にアスタリスクを入れるべきではありませんか?
user764754 2015年

2
@ user764754プルすると、作業コピーに変更が反映されます(解決する必要がある競合もいくつかあります)。それでもローカルリポジトリにコミットする必要があります。
Justus Romijn、2015年

@JustusRomijn:イラストありがとうございます。リポジトリの状態に対するリセット、チェリーピックなどの操作の影響を示すことにより、ダイアグラムをより包括的にできるとすばらしいと思います。
jith912 2015年

106

私もこれに苦労しています。実際、私はまったく同じ質問のグーグル検索でここに来ました。これらすべての答えを読んで、ようやく頭の中に絵が描かれました。2つのリポジトリと1つのサンドボックスの状態と、それらのバージョンを見ながら時間をかけて実行されたアクションを見て、これを理解することにしました。これが私が思いついたものです。どこかで失敗した場合は修正してください。

フェッチ付きの3つのリポジトリ:

---------------------     -----------------------     -----------------------
- Remote Repo       -     - Remote Repo         -     - Remote Repo         -
-                   -     - gets pushed         -     -                     -
- @ R01             -     - @ R02               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Repo        -     - Local Repo          -     - Local Repo          -
- pull              -     -                     -     - fetch               -
- @ R01             -     - @ R01               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Sandbox     -     - Local Sandbox       -     - Local Sandbox       -
- Checkout          -     - new work done       -     -                     -
- @ R01             -     - @ R01+              -     - @R01+               -
---------------------     -----------------------     -----------------------

プル付きの3つのリポジトリ

---------------------     -----------------------     -----------------------
- Remote Repo       -     - Remote Repo         -     - Remote Repo         -
-                   -     - gets pushed         -     -                     -
- @ R01             -     - @ R02               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Repo        -     - Local Repo          -     - Local Repo          -
- pull              -     -                     -     - pull                -
- @ R01             -     - @ R01               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Sandbox     -     - Local Sandbox       -     - Local Sandbox       -
- Checkout          -     - new work done       -     - merged with R02     -
- @ R01             -     - @ R01+              -     - @R02+               -
---------------------     -----------------------     -----------------------

これは、フェッチが非常に重要である理由を理解するのに役立ちました。


読むのは難しくありません。ボックスはリポジトリのステータスを表します。各行では、ボックスの行2で報告された操作の後に、左から右に時間的に変化します。ラベルR0nはgitのタグであり、+が付いたタグはまだコミットされていないものです。Sanboxは、コミットされたものが保存されるrepoフォルダーとは異なる作業フォルダーに使用されます。
user1708042 2017

96

GIT FetchGIT Pullの違いは、次のシナリオで説明できます:( 写真は言葉よりも雄弁であることを念頭に置いて!)、図で表現しました)

チームメンバーとプロジェクトに取り組んでいる例を見てみましょう。したがって、彼らはプロジェクトの1つのメインブランチになり、すべてのコントリビューターはそれを自分のローカルリポジトリにフォークし、このローカルブランチでモジュールを変更/追加してからメインブランチにプッシュバックする必要があります。

したがって、 ローカルリポジトリのメインプロジェクトをフォークしたときの2つのブランチの初期状態は次のようになります(ABおよびCプロジェクトのモジュールはすでに完了しています)。

ここに画像の説明を入力してください

さて、あなたは新しいモジュールに作業を開始している(としD)、あなたが完了したとき、Dあなたはメインブランチにプッシュするモジュールを、しかし、一方で何が起こるかは、あなたのチームメイトの一つは、新しいモジュールを開発したことがありEFそして修正しますC
つまり、ローカルリポジトリにプロジェクトの元の進捗状況が不足しているため、メインブランチに変更をプッシュすると競合が発生し、モジュールDが誤動作する可能性があります。

ここに画像の説明を入力してください

このような問題を回避し、プロジェクトの当初の進捗と並行して作業するには、次の2つの方法があります。

1. Git Fetch-これにより、ローカルブランチに存在しないorigin / mainブランチプロジェクトに加えられたすべての変更がダウンロードされます。そして、Git Mergeコマンドがリポジトリまたはブランチにフェッチされた変更を適用するのを待ちます。

ここに画像の説明を入力してください

これで、ファイルをリポジトリにマージする前に、ファイルを注意深く監視できます。またD、Modifiedのため、必要に応じて変更することもできますC

ここに画像の説明を入力してください

2. Git Pull-これにより、ローカルブランチがorigin / mainブランチで更新されます。つまり、実際には、Git FetchとGit mergeが次々に組み合わされます。 ただし、これにより競合が発生する可能性があるため、クリーンコピーでGit Pullを使用することをお勧めします。

ここに画像の説明を入力してください


1
「Main Branch」を「Remote Repo」に変更できるとしたら、それは素晴らしい答えです。
Qibiron Who

87

私たちは単に言う:

git pull == git fetch + git merge

を実行する場合git pull、データをローカルにマージする必要はありません。を実行する場合、ローカルマシンに最新のコードを取得git fetchするgit mergeために実行する必要があることを意味します。そうしないと、ローカルマシンのコードはマージしないと変更されません。

したがって、Git Guiでは、フェッチを行うときにデータをマージする必要があります。Fetch自体はローカルでコードを変更しません。一度フェッチして確認することで、コードを更新するときにそれを確認できます。変更されないコード。次に、マージします...変更されたコードが表示されます。


3
私はむしろ言いたいですgit pull == git fetch + git merge:)
melvynkim 2013年

2
しかしgit pull --rebase = git fetch + git rebase
ティノ2013

83

git fetchリモートサーバーからローカルリポジトリの追跡ブランチにコードをプルダウンします。リモートに名前が付いている場合origin(デフォルト)、これらの枝は内にあるであろうorigin/例えば、origin/masterorigin/mybranch-123、などが挙げられる。これらは、あなたの現在の支店ではありません、彼らはローカルサーバからそれらの枝のコピー。

git pullgit fetchが、その後そのブランチのあなたの現在のローカルバージョンに追跡ブランチからコードをマージします。その変更の準備がまだできていない場合は、git fetchまず最初に。


78

git fetchあなたができるように、リモートブランチを取得しますgit diffgit mergeそれらの現在のブランチに。git pull現在のブランチによって追跡されているリモート分岐でフェッチを実行し、結果をマージします。を使用git fetchして、ローカルブランチとマージする必要なく、リモートブランチに更新があるかどうかを確認できます。


73

Gitフェッチ

ローカルブランチへの変更を、originからfetchを介してダウンロードします。Fetchは、他の人が行ったすべてのコミットをリモートリポジトリに要求しますが、ローカルリポジトリにはありません。Fetchはこれらのコミットをダウンロードし、ローカルリポジトリに追加します。

Gitマージ

mergeコマンドを使用して、フェッチによってダウンロードされた変更を適用できます。Mergeはフェッチから取得したコミットを取得して、ローカルブランチに追加しようとします。マージはローカル変更のコミット履歴を保持するため、ブランチをプッシュで共有すると、Gitは他の人がどのように変更をマージできるかを認識します。

Git Pull

フェッチとマージは、2つを組み合わせるコマンドpullが作成されるほど頻繁に一緒に実行されます。プルはフェッチを行ってからマージを行い、ダウンロードしたコミットをローカルブランチに追加します。


51

唯一の違いgit pullとはgit fetchその次のとおりです。

git pull リモートブランチからプルしてマージします。

git fetch リモートブランチからのみフェッチしますが、マージしません

つまり、git pull = git fetch + git merge ...


1
そして、gitがコミットに遅れをとっていて「早送り」できるとGitが判断した場合も、どちらも役に立ちませんrm -rf。愚かなGit、仕事に戻ることができるように、私に最新の情報を知らせてください。
Chris K

47

簡単に言えば、インターネットに接続せずに飛行機に飛び乗るつもりなら...出発する前に、そうすることができますgit fetch origin <master>。すべての変更をコンピューターにフェッチしますが、ローカルの開発/ワークスペースから分離します。

飛行機では、ローカルワークスペースに変更を加え、それをフェッチしたものとマージし、インターネットに接続せずに潜在的なマージの競合をすべて解決できます。そして、誰かがリモートリポジトリに競合する新しい変更を加えていない限り、目的地に到着しgit push origin <branch>たら、コーヒーを飲みに行きます。


この素晴らしいアトラシアンチュートリアルから

このgit fetchコマンドは、コミット、ファイル、および参照をリモートリポジトリからローカルリポジトリにダウンロードします。

フェッチとは、他のが取り組んでいることを確認したいときに行うことです。中央の履歴の進行状況を確認できるという点でSVNの更新と似ていますが、実際に変更をリポジトリにマージする必要はありません。Gitはフェッチされたコンテンツを既存のローカルコンテンツから分離しますローカルの開発作業にはまったく 影響しません。フェッチされたコンテンツは、git checkoutコマンドを使用して明示的にチェックアウトする必要があります。これにより、ローカルリポジトリと統合する前にコミットを確認する安全な方法をフェッチできます。

場合は、リモートリポジトリからコンテンツをダウンロード、git pullおよびgit fetchコマンドは、タスクを達成するために用意されています。git fetch2つのコマンドの「安全な」バージョンを検討でき ます。リモートコンテンツはダウンロードされますが、ローカルリポジトリの動作状態は更新されず、現在の作業はそのまま残ります。git pullより積極的な代替手段です。アクティブなローカルブランチのリモートコンテンツをダウンロードし、すぐに実行git mergeして、新しいリモートコンテンツのマージコミットを作成します。保留中の変更が進行中の場合、これにより競合が発生し、マージ競合解決フローが開始されます。


git pull

  • 孤立はありません。
  • それはあなたのローカル開発に影響を与えます。
  • 明示的にチェックアウトする必要はありません。暗黙的にgit merge
  • 基本的に安全ではありません。それは攻撃的です。
  • 異なりgit fetch、それはあなただけの影響を与えるところ.git/refs/remotes、gitのプルが影響するの両方あなた.git/refs/remotes .git/refs/heads/

うーん...それで、作業コピーをgit fetchで更新しない場合、どこで変更を加えますか?Gitフェッチは新しいコミットをどこに保存しますか?

すばらしい質問です。作業コピーから隔離された場所に配置します。しかし、再びどこに?確認してみましょう。

プロジェクトディレクトリ(つまり、gitコマンドを実行する場所)で次を実行します。

  1. ls。ファイルとディレクトリが表示されます。何もかっこいいと思います。

  2. さあls -a。これはドットファイルを表示します。つまり、.Youで始まるファイルは、という名前のディレクトリを見ることができます.git

  3. してくださいcd .git。これは明らかにディレクトリを変更します。
  4. ここからが楽しい部分です。しますls。ディレクトリのリストが表示されます。探していrefsます。してくださいcd refs
  5. すべてのディレクトリの中に何があるかを見るのは興味深いですが、そのうちの2つに注目しましょう。headsremotescdそれらをチェックするのにも使用します。
  6. どれでも git fetchあなたが行うことは、内のアイテムが更新されます/.git/refs/remotesディレクトリを。/.git/refs/headsディレクトリの内容は更新されません。
  7. Any git pullは最初にを実行git fetchし、/.git/refs/remotesディレクトリ内のアイテムを更新してから、ローカルとマージしてから、/.git/refs/headsディレクトリ内のヘッドを変更します。

「git fetch」どこに配置されていますか?

また、Gitブランチの命名規則の投稿から「スラッシュ表記」を探してください。これは、Gitがさまざまなディレクトリにどのように配置するかをよりよく理解するのに役立ちます。


実際の違いを確認するには

ただやる:

git fetch origin master
git checkout master

リモートマスターが更新された場合は、次のようなメッセージが表示されます。

Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

あなたがしなかった場合fetchだけでしたgit checkout master、あなたの地元のgitが追加2つのコミットがあることを知ることはできません。そしてそれはただ言うでしょう:

Already on 'master'
Your branch is up to date with 'origin/master'.

しかし、それは時代遅れで間違っています。それは、gitが知っていることにのみ基づいてフィードバックを提供するからです。まだプルダウンされていないことは、新しいコミットには気づいていません...


ローカルでブランチで作業しているときにリモートで行われた新しい変更を確認する方法はありますか?

一部のIDE(Xcodeなど)は非常にスマートで、aの結果を使用し、git fetch現在の作業ブランチのリモートブランチで変更されたコード行に注釈を付けることができます。その行がローカル変更とリモートブランチの両方によって変更されている場合、その行には赤の注釈が付けられます。これはマージの競合ではありません。これはマージの競合の可能性があります。これgit pullは、リモートブランチから実行する前に、将来のマージの競合を解決するために使用できるヘッドアップです。

ここに画像の説明を入力してください


楽しいヒント:

リモートブランチをフェッチした場合、たとえば次のようにしました:

git fetch origin feature/123

次に、これはリモートディレクトリに移動します。ローカルディレクトリではまだ利用できません。ただし、DWIMを使用すると、リモートブランチへのチェックアウトが簡単になります(つまり、次のことを行います)。

git checkout feature/123

あなたはもはやする必要はありません:

git checkout -b feature/123 origin/feature/123

詳しくはこちらをご覧ください


1
私はこの答えが好きです
Kid_Learning_C

44

Gitでは、新しいコミットの後に、年代順に古いコミットを適用できます。このため、リポジトリ間でコミットを転送する作業は、次の2つのステップに分かれています。

  1. リモートブランチからローカルリポジトリ内のこのリモートブランチのコピーに新しいコミットをコピーしています。

    (レポからレポへの操作) master@remote >> remote/origin/master@local

  2. ローカルブランチへの新しいコミットの統合

    (内部レポ操作) remote/origin/master@local >> master@local

ステップ2を実行するには2つの方法があります。

  1. 最後の共通の祖先の後にローカルブランチをフォークし、ローカルリポジトリに固有のコミットと並行して新しいコミットを追加します。コミットをマージし、フォークを閉じることで確定します。
  2. 最後の共通の祖先の後に新しいコミットを挿入し、ローカルリポジトリに固有のコミットを再適用します。

git用語、ステップ1は、git fetchステップ2であり、git merge又はgit rebase

git pullでありgit fetchgit merge


37

Gitは、次の2つのコマンドを使用して、最新バージョンのブランチをリモートからローカルに取得します。

  1. git fetch:Gitはリモートからローカルに最新バージョンを取得しますが、自動的にはマージされません。      git fetch origin master git log -p master..origin/master git merge origin/master

         上記のコマンドは、リモートからオリジンマスターブランチにオリジンからメインブランチの最新バージョンをダウンロードすることを意味します。次に、ローカルマスターブランチとオリジンマスターブランチを比較します。最後に、マージします。

  2. git pull:Gitはリモートから最新バージョンを取得し、ローカルにマージします。

        git pull origin master

         上記のコマンドはgit fetchおよびと同等git mergeです。実際git fetchには、マージの前に変更を確認してマージするかどうかを判断できるため、おそらくより安全です。


37

違いは何であるgit pullとはgit fetch

これを理解するには、まずローカルgitがローカルリポジトリだけでなく、リモートリポジトリのローカルコピーも保持することを理解する必要があります。

git fetchリモートリポジトリのローカルコピーを最新の状態にします。たとえば、リモートリポジトリがGitHubの場合、リモートリポジトリで行った変更をリモートリポジトリのローカルコピーにフェッチすることができます。これにより、比較やマージなどの操作を実行できます。

git pull一方、リモートリポジトリの変更は、独自のコードを保持する場所に反映されます。通常、git pullgit fetch最初にリモートリポジトリのローカルコピーを最新の状態にしてから、変更内容を独自のコードリポジトリと作業コピーにマージします。


35

git pull ==(git fetch + git merge)

git fetchはローカルブランチを変更しません。

目的のプロジェクト用にリモートが設定されたローカルリポジトリがある場合は、git fetchを使用して、既存のリモートのすべてのブランチとタグを取得できます。... Fetchはローカルブランチに変更を加えないため、リモートブランチをペアのローカルブランチとマージして、新しくフェッチした変更を組み込む必要があります。githubから


34

明確でシンプルであることを目指しています。

gitのプルコマンドは、実際にあるshortcutためにgitのフェッチに続いてgitのマージgitのリベースの構成に応じてコマンド。Gitリポジトリを構成して、git pullがフェッチとそれに続くリベースになるようにすることができます。


33

初心者のためのシンプルなグラフィック表現、

ここに画像の説明を入力してください

ここに、

git pull  

リポジトリからコードをフェッチし、ローカルでリベースします... git pullでは、新しいコミットが作成される可能性があります。

しかし、

git fetch

リポジトリからコードをフェッチし、次を使用して手動でリベースする必要があります git rebase

例:サーバーマスターからフェッチして、ローカルマスターにリベースします。

1)git pull(リベースは自動的に行われます):

git pull origin master

ここで、オリジンはリモートレポマスター、ブランチです

2)git fetch(手動でリベースする必要があります):

git fetch origin master

サーバーの変更をオリジンからフェッチします。自分でリベースするまでローカルにあります。コードをチェックして手動で競合を修正する必要があります。

git rebase origin/master

これにより、コードがローカルにリベースされます。その前に、正しいブランチにいることを確認してください。


素晴らしいグラフですが、グラフが「マージ」と言っているときに「リベース」を使用する理由を説明したいと思うかもしれません。
Guntram Blohmはモニカ

2
mergeは別のブランチコミットを表し、参照としてコミットを含む新しいコミットを生成します。しかし、リベースは別のブランチからコミットを複製し、複製するのではなく新しいコミットを作成し
ません

33

実際、Gitは独自のコードとリモートリポジトリのコピーを保持しています。

このコマンドgit fetchは、リモートリポジトリからデータを取得することにより、ローカルコピーを最新の状態にします。これが必要な理由は、他の誰かがコードにいくつかの変更を加えた可能性があり、あなたは自分を更新し続けたいと思っているからです。

このコマンドgit pullは、リモートリポジトリの変更を独自のコードを保持する場所に持ってきます。通常、git pullこれを行うには、最初に「git fetch」を実行してリモートリポジトリのローカルコピーを最新の状態にしてから、変更を独自のコードリポジトリと作業コピーにマージします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.