git pull
とはどう違いgit fetch
ますか?
38 に答える
簡単にgit pull
言うと、 a のgit fetch
後に a を実行しgit merge
ます。
git fetch
の下にあるリモート追跡ブランチをいつでも更新できますrefs/remotes/<remote>/
。この操作は、 の下にある独自のローカル ブランチrefs/heads
を変更することはなく、作業コピーを変更せずに安全に実行できます。バックグラウンドで cron ジョブを定期的に実行している人もgit fetch
います (ただし、これを行うことはお勧めしません)。
Agit pull
は、他のリモート トラッキング ブランチも更新しながら、ローカル ブランチをリモート バージョンで最新の状態にするために行うことです。
のGitドキュメントからgit pull
:
デフォルトのモードでは、 の後に続く
git pull
の省略形です。git fetch
git merge FETCH_HEAD
を使用する
pull
と、Gitは自動的にマージを試みます。コンテキストに依存するため、Gitはプルされたコミットを現在作業中のブランチにマージします。 最初にコミットを確認せずにpull
、コミットを自動的にマージします。ブランチを注意深く管理しないと、頻繁に競合が発生する可能性があります。すると
fetch
、Gitは現在のブランチに存在しないターゲットブランチからコミットを収集し、ローカルリポジトリに保存します。ただし、それらを現在のブランチとマージすることはありません。これは、リポジトリを最新の状態に保つ必要があるが、ファイルを更新すると壊れることがある何かに取り組んでいる場合に特に便利です。merge
コミットを現在のブランチに統合するには、後で使用する必要があります。
git の設計哲学を、SVN のような従来のソース管理ツールの哲学と対比することが重要です。
Subversion は、クライアント/サーバー モデルで設計および構築されました。サーバーである単一のリポジトリがあり、複数のクライアントがサーバーからコードを取得して作業し、それをサーバーにコミットできます。操作を実行する必要がある場合、クライアントは常にサーバーに接続できると想定されています。
Git は、中央リポジトリを必要としない、より分散されたモデルをサポートするように設計されています (ただし、必要に応じて中央リポジトリを使用することもできます)。また、git は、クライアントと「サーバー」が同時にオンラインである必要がないように設計されています。Git は、信頼性の低いリンクにいる人々が電子メールでコードを交換できるように設計されています。完全に切断された状態で作業し、CD を焼いて git 経由でコードを交換することが可能です。
このモデルをサポートするために、git はコードを含むローカル リポジトリと、リモート リポジトリの状態を反映する追加のローカル リポジトリを維持します。リモート リポジトリのコピーをローカルに保持することで、リモート リポジトリにアクセスできない場合でも、git は必要な変更を把握できます。後で変更を他の人に送信する必要がある場合、git はリモート リポジトリに既知の時点から変更のセットとしてそれらを転送できます。
git fetch
は、「リモート リポジトリのローカル コピーを最新の状態にする」というコマンドです。git pull
は、「リモート リポジトリの変更を、自分のコードを保持している場所に持ち込む」と述べています。
通常、リモート リポジトリのローカル コピーを最新の状態にするために をgit pull
実行してから、変更を独自のコード リポジトリと場合によっては作業コピーにマージします。git fetch
ワークステーションには、プロジェクトのコピーが少なくとも 3 つあることがよくあります。1 つのコピーは、独自のコミット履歴を持つ独自のリポジトリです。2 番目のコピーは、編集およびビルドしている作業コピーです。3 番目のコピーは、リモート リポジトリのローカルの「キャッシュされた」コピーです。
の使用例の 1 つgit fetch
は、最後のプル以降のリモート ブランチの変更を次のように通知することです...実際のプルを実行する前に確認できます。これにより、現在のブランチと作業コピーのファイルが変更される可能性があります。
git fetch
git diff ...origin
参照: https://git-scm.com/docs/git-diff diff コマンドのダブル ドットおよびトリプル ドット構文について
違いを理解するのに少し時間がかかりましたが、これは簡単な説明です。master
あなたのローカルホストではブランチです。
リポジトリのクローンを作成すると、リポジトリ全体がローカル ホストにフェッチされます。これは、その時点で、オリジン/マスター ポインターがHEAD
あり、マスターが同じ を指していることを意味しますHEAD
。
作業を開始してコミットを行うときは、マスター ポインターをHEAD
+ コミットに進めます。ただし、オリジン/マスター ポインターは、クローン作成時のものを指しています。
したがって、違いは次のようになります。
- a を実行する
git fetch
と、リモート リポジトリ ( GitHub ) 内のすべての変更が取得され、オリジン/マスター ポインターが に移動されHEAD
ます。その間、ローカル ブランチ マスターは、その場所を指し続けます。 - を実行する
git pull
と、基本的にフェッチが行われ (前に説明したように)、新しい変更があればマスター ブランチにマージされ、ポインタが に移動しますHEAD
。
git-pull - 別のリポジトリまたはローカル ブランチから取得してマージする あらすじ ギットプル… 説明 指定されたパラメータで git-fetch を実行し、git-merge を呼び出して ヘッドを現在のブランチに取得しました。--rebase を指定すると、git-rebase を呼び出します git-merge の代わりに。 使用できることに注意してください。(現在のディレクトリ) プルする <repository> として ローカル リポジトリから — これは、ローカル ブランチをマージするときに役立ちます。 現在のブランチに。 また、オプションは git-pull 自体と基礎となる git-merge を対象としていることにも注意してください。 git-fetch 用のオプションの前に指定する必要があります。
履歴をマージしたい場合はプルし、誰かがこのあたりの記事にタグを付けているので、単に「コードが欲しい」場合はフェッチします。
リモート リポジトリからフェッチし、違いを確認してから、プルまたはマージできます。
これは、リモート リポジトリと呼ばれるリモート リポジトリと、リモート ブランチを追跡するorigin
というブランチの例です。master
origin/master
git checkout master
git fetch
git diff origin/master
git rebase origin master
短くて簡単な答えは、git pull
単に.git fetch
git merge
あなたが好むと好まざるとにかかわらず、自動的にマージgit pull
されることに注意することは非常に重要です。もちろん、これによりマージの競合が発生する可能性があります。リモートがで、ブランチが であるとしましょう。プルする前に、潜在的なマージの競合についてある程度の考えを持っている必要があり、それに応じてローカル ブランチを準備できます。origin
master
git 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-pull
2.3.5
これは潜在的に危険な操作モードです。歴史を書き換えますが、その歴史をすでに公開しているとはうまくいきません。git-rebase(1) を注意深く読んでいない限り、このオプションを使用しないでください。
このインタラクティブなグラフィカル表現は、git を理解するのに非常に役立ちます: http://ndpsoftware.com/git-cheatsheet.html
git fetch
リモートからローカルリポジトリに変更を「ダウンロード」するだけです。git pull
変更をダウンロードし、現在のブランチにマージします。「そのデフォルト モードでは、 の後に続くgit pull
の省略形です。」git fetch
git merge FETCH_HEAD
ボーナス:
上記の回答のプルとフェッチについて言えば、興味深いトリックを共有したいと思います。
git pull --rebase
この上記のコマンドは、多くの時間を節約した私の git ライフの中で最も便利なコマンドです。
新しいコミットをサーバーにプッシュする前に、このコマンドを試すと、サーバーの最新の変更が自動的に同期され (フェッチ + マージを使用)、コミットが git ログの一番上に配置されます。手動のプル/マージについて心配する必要はありません。
詳細については、http : //gitolite.com/git-pull--rebaseをご覧ください。
これらを把握するために、状況を視覚的に表現するのが好きです。他の開発者もそれを見たいと思うかもしれないので、ここに私の追加があります。全てが正しいとは言い切れませんので、間違い等ありましたらコメントお願いします。
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 FetchとGIT Pullの違いは、次のシナリオで説明できます 。
チームメンバーと一緒にプロジェクトに取り組んでいる例を見てみましょう。したがって、プロジェクトの 1 つのメイン ブランチがあり、すべての貢献者はそれを自分のローカル リポジトリにフォークしてから、このローカル ブランチで作業してモジュールを変更/追加し、メイン ブランチにプッシュ バックする必要があります。
したがって、
ローカル リポジトリでメイン プロジェクトをフォークしたときの 2 つのブランチの初期状態A
は次のようになります ( 、B
およびC
プロジェクトのモジュールは既に完了しています)。
ここで、新しいモジュール (と仮定D
) の作業を開始し、モジュールが完成したら、D
それをメイン ブランチにプッシュしたいと考えています。
そのため、ローカル リポジトリがプロジェクトの元の進行状況に遅れをとっているため、変更をメイン ブランチにプッシュすると競合が発生し、モジュールが誤動作する可能性があります。E
F
C
D
このような問題を回避し、プロジェクトの元の進行状況と並行して作業するには、次の 2 つの方法があります。
1. Git Fetch -これにより、オリジン/メイン ブランチ プロジェクトに加えられた、ローカル ブランチには存在しないすべての変更がダウンロードされます。そして、Git Merge コマンドがフェッチされた変更をリポジトリまたはブランチに適用するのを待ちます。
したがって、ファイルをリポジトリにマージする前に、ファイルを注意深く監視できます。D
Modified により、必要に応じて変更することもできますC
。
2. Git プル- これにより、ローカル ブランチがオリジン/メイン ブランチで更新されます。つまり、実際には、Git Fetch と Git マージを次々と組み合わせて実行します。 ただし、これにより競合が発生する可能性があるため、クリーン コピーで Git Pull を使用することをお勧めします。
私もこれに苦労しました。実際、私はまったく同じ質問のグーグル検索でここに着きました。これらすべての答えを読んで、最終的に私の頭の中に絵が描かれ、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+ -
--------------------- ----------------------- -----------------------
これは、フェッチが非常に重要である理由を理解するのに役立ちました。
私たちは単に言います:
git pull == git fetch + git merge
を実行する場合git pull
、データをローカルにマージする必要はありません。を実行する場合は、ローカル マシンに最新のコードを取得するためにgit fetch
実行する必要があることを意味します。git merge
そうしないと、マージしないとローカル マシン コードが変更されません。
そのため、Git Gui では、フェッチするときにデータをマージする必要があります。Fetch 自体はローカルでコードを変更しません。一度フェッチして確認することで、コードを更新するときに確認できます。コードは変更されません。次に、マージします...変更されたコードが表示されます。
git fetch
リモート サーバーからローカル リポジトリの追跡ブランチにコードをプルダウンします。リモートに名前が付けられている場合origin
(デフォルト)、これらのブランチはorigin/
、たとえばorigin/master
、origin/mybranch-123
などの中にあります。これらは現在のブランチではなく、サーバーからのブランチのローカルコピーです。
git pull
を行いますgit fetch
が、追跡ブランチからのコードをそのブランチの現在のローカル バージョンにマージします。その変更の準備ができていない場合は、git fetch
まず最初に行ってください。
git fetch
リモートブランチを取得して、現在のブランチでそれらを実行できるようにしますgit diff
。現在のブランチによって追跡されるリモート ブランチでフェッチを実行し、結果をマージします。ローカル ブランチとマージする必要なく、リモート ブランチに更新があるかどうかを確認するために使用できます。git merge
git pull
git fetch
Git フェッチ
ローカル ブランチへの変更は、オリジンからフェッチを通じてダウンロードします。Fetch は、他の人が作成したすべてのコミットをリモート リポジトリに要求しますが、ローカル リポジトリにはありません。Fetch はこれらのコミットをダウンロードし、ローカル リポジトリに追加します。
Git マージ
merge コマンドを使用して、フェッチによってダウンロードされた変更を適用できます。Merge は fetch から取得したコミットを受け取り、それらをローカル ブランチに追加しようとします。マージはローカルの変更のコミット履歴を保持するため、ブランチをプッシュで共有すると、Git は他のユーザーが変更をマージする方法を認識します。
Gitプル
フェッチとマージは頻繁に一緒に実行されるため、2 つを組み合わせたプルというコマンドが作成されました。プルはフェッチを行い、次にマージを実行して、ダウンロードしたコミットをローカル ブランチに追加します。
git pullコマンドは、実際にshortcut
はgit fetchの後に、構成に応じてgit mergeまたはgit rebaseコマンドが続きます。git pullがフェッチの後にリベースが続くように、Git リポジトリを構成できます。
git pull
とはどう違いgit fetch
ますか?
これを理解するには、まず、ローカル git がローカル リポジトリだけでなく、リモート リポジトリのローカル コピーも保持していることを理解する必要があります。
git fetch
リモート リポジトリのローカル コピーを最新の状態にします。たとえば、リモート リポジトリが GitHub の場合、リモート リポジトリで行われたすべての変更をリモート リポジトリのローカル コピーにフェッチすることができます。これにより、比較やマージなどの操作を実行できます。
git pull
一方、リモートリポジトリの変更を独自のコードを保持する場所に落とします。通常、git pull
最初git fetch
にリモート リポジトリのローカル コピーを最新の状態にしてから、変更を独自のコード リポジトリと、場合によっては作業コピーにマージします。
実際には、Git は独自のコードとリモート リポジトリのコピーを保持しています。
このコマンドgit fetch
は、リモート リポジトリからデータを取得して、ローカル コピーを最新の状態にします。これが必要な理由は、他の誰かがコードに何らかの変更を加えた可能性があり、自分自身を最新の状態に保ちたいからです。
このコマンドgit pull
は、リモート リポジトリ内の変更を、独自のコードを保持する場所にもたらします。通常、git pull
これは、最初に「git fetch」を実行してリモート リポジトリのローカル コピーを最新の状態にしてから、変更を独自のコード リポジトリと場合によっては作業コピーにマージすることによって行われます。
git pull = git fetch + git merge
gitプル
1 つのコマンドで 2 つの機能を実行します。
リモート ブランチに加えられたすべての変更を取得し、それらの変更をローカル ブランチにマージします。--rebase を渡すことでプルの動作を変更することもできます。マージとリベースの違いは、ここで読むことができます
git フェッチ
Git fetch は git pull の半分の作業しか行いません。リモートの変更をローカル リポジトリに取り込むだけで、ブランチには適用しません。これらの変更を明示的に適用する必要があります。これは次のように行うことができます。
git fetch
git rebase origin/master
git の性質に留意する必要があります。リモートとローカル ブランチがあります (必ずしも同じである必要はありません)。他のソース管理システムと比較すると、これは少し当惑する可能性があります。
通常、リモートをチェックアウトすると、リモートを追跡するローカル コピーが作成されます。
git fetch はリモート ブランチで動作し、情報を更新します。
実際には、他の SWE が同じブランチで作業している場合に当てはまり、小規模な 1 つの開発、1 つのブランチ、1 つのプロジェクトのシナリオではめったにありません。
ローカル ブランチでの作業はそのままです。変更をローカル ブランチに反映するには、リモート ブランチからの変更をマージ/リベースする必要があります。
git pull はこの 2 つの手順を正確に実行します (つまり、マージではなくリベースへの --rebase )。
ローカル履歴とリモート履歴に競合がある場合、変更を公開するために git push 中にマージを行う必要があります。
したがって、実際には、作業環境の性質と何を使用するかによって異なります。