git pull コマンドは、リモートリポジトリからコンテンツをフェッチしてダウンロードし、そのコンテンツと一致するようローカルリポジトリを即時に更新するために使用されます。中央リポジトリにおける変更のローカルリポジトリへのマージは、Git ベースのコラボレーションワークフローではよく行われるタスクです。git pull コマンドは、実際には他の 2 つのコマンド (git fetch とその後の git merge) を組み合わせたものです。操作の第 1 ステージでは、git pull により、git fetch が、HEAD がポイントされたローカルブランチにスコープされて実行されます。コンテンツがダウンロードされると、git pull のマージワークフローが開始されます。新しいマージコミットが作成され、HEAD が新しいコミットをポイントするよう更新されます。

git pull の用途

仕組み

git pull コマンドでは、最初に git fetch が実行され、指定されたリモートリポジトリからコンテンツがダウンロードされます。次に git merge が実行され、リモートコンテンツ参照がマージされて、新しいローカルマージコミットへと進みます。プルとマージのプロセスをより分かりやすく説明するため、master ブランチと origin リモートを含むリポジトリを例として使用します。

このシナリオでは、git pull により、ローカルと master が分岐したポイントからの変更がすべてダウンロードされます。この例では、そのポイントは E です。git pull により、分岐リモートコミット (A-B-C) がフェッチされます。その後、プルプロセスにより、新しい分岐リモートコミットのコンテンツを含む新しいローカルマージコミットが作成されます。

上の図には、新しいコミット H があります。このコミットは、リモート A-B-C コミットのコンテンツおよび統合されたログメッセージを含む新しいマージコミットです。この例は、いくつかの git pull マージ戦略の 1 つです。--rebase オプションを git pull に渡し、マージコミットの代わりにリベースマージの戦略を使用できます。次の例は、リベースプルの動作を示しています。最初の図の開始ポイントで、git pull --rebase を実行したと想定します。

この図では、リベースプルによって新しい H コミットが作成されていません。代わりに、リベースによってリベースコミット A--B--C がコピーされ、ローカルの origin/master コミット履歴に追加されています。

よく使われるオプション

git pull <remote>

現在のブランチの指定したリモートにおけるコピーをフェッチして、それを現在のブランチに即時マージします。これは、git fetch <remote> とそれに続く git merge origin/<current-branch> の実行と同等です。

git pull --no-commit <remote>

既定の呼び出しと同様に、リモートコンテンツはフェッチされますが、新しいマージコミットは作成されません。

git pull --rebase <remote>

前のプルと同じく、git merge を使用してリモートブランチをローカルブランチと統合するのではなく、git rebase を使用します。

git pull --verbose

プル中に詳細出力が行われ、ダウンロードされているコンテンツとマージの詳細が表示されます。

git pull の説明

git pull コマンドは、SVN における svn update コマンドに相当するものとして捉えられます。このコマンドは、ローカルリポジトリを中央リポジトリに同期する簡便な方法です。次の図は、プルを実行したときの各々のステップを説明したものです。

最初はローカルリポジトリが origin と同期されている状態だったものが、git fetch コマンドを実行したところ origin の master に最後に確認した時点から進行があったことが明らかになりました。ここで git merge によってリモート master がローカル master に即時にマージされます。

git pull と同期

git pull は、リモートコンテンツの「同期」に関連する多数のコマンドの 1 つです。git remote コマンドは、同期コマンドが実行されるリモートエンドポイントを指定するために使用されます。git push コマンドは、リモートリポジトリにコンテンツをアップロードするために使用されます。

git fetch コマンドは、git pull と混同されがちです。どちらも、リモートコンテンツのダウンロードに使用されます。git pullget fetch には安全上の重要な違いがあり、git fetch は「安全」なオプション、git pull は安全ではないオプションと考えられます。git fetch ではリモートコンテンツがダウンロードされ、ローカルリポジトリの状態は変更されません。一方、git pull ではリモートコンテンツがダウンロードされ、そのコンテンツに合わせてローカルの状態の変更が即時に試行されます。これにより、ローカルリポジトリで意図しない競合状態が発生する可能性があります。

リベースを用いたプル

--rebase オプションは、不要なマージコミットを防止することによって時系列の履歴を確保するために使用できます。多くの開発者はマージよりもリベースを優先します。これは、「他のすべての人が行った変更の上に自分の変更を加えたい」と言っているようなものです。その意味では、git pull--rebase フラグを指定して使用した場合、単純な git pull よりも svn update に似ています。

実際、--rebase フラグを指定したプル操作は非常に一般的なワークフローになっているため、それを行うための専用の設定コマンドが用意されています。

git config --global branch.autosetuprebase always

このコマンドを実行すると、すべての git pull コマンドで統合の際に git merge ではなく git rebase が使用されます。

git pull の例

以下の例は、一般的なシナリオで git pull を使用する方法を示しています。

既定の動作

git pull

git pull の既定呼び出しの実行は、git fetch origin HEAD および git merge HEAD に相当します (HEAD は現在のブランチをポイントする参照)。

リモートの git pull

git checkout new_feature
git pull <remote repo>

この例では、最初にチェックアウトを実行し、<newfeature> ブランチに切り替えます。その後、git pull が実行され、<remote repo> が渡されます。これにより、newfeature ブランチが <remote repo> から暗示的にプルされます。ダウンロードが完了すると、git merge が開始されます。

マージの代わりの git pull リベース

次の例は、リベースを使用した中央リポジトリの master ブランチとの同期方法を示したものです。

git checkout master
git pull --rebase origin

このコマンドを実行すると、他の開発者の作業成果がすべて反映されたものの上に、ローカルの変更が加えられるようになります。