git pullコマンド: --force、--rebase オプション、差分の取得、競合の解決
この記事では、git pull
コマンドについてよくある質問を取り上げます。
基本的な概念と使い方、--force
オプション、--rebase
オプション、競合の解決方法について説明します。
1. git pull を理解する
git pull
コマンドは、リモートリポジトリの変更をローカルリポジトリに適用します。
これは 2 つのステップで行われます。git pull
コマンドは内部的に git fetch
コマンドを使用して、リモートリポジトリの変更をローカルに取り込んでキャッシュします、
git merge コマンド を使用して、それらの変更をローカルリポジトリにマージします。
リモートリポジトリのコミットが直前であれば、早送りで簡単にプルを完了させることができます。 しかし、git merge post が示すように、マージ中にコンフリクトが発生する可能性があります。 オプションとして、マージの代わりにリベース戦略を使うこともできます。
使い方は簡単です。リモートリポジトリの特定のブランチから変更を取り込む場合は、リモート名とブランチ名を指定します。
$ git pull origin main
リモートリポジトリ名とブランチ名を以下のように書かないと、現在の作業ブランチや設定によっては、意図しない結果になることがあります。 可能な限り、上のコマンドのようにリモートリポジトリ名とブランチ名を一緒に使ってください。
$ git pull
では、それぞれの状況で `git pull' を実行した結果を見てみよう。
1.1 早送り戦略
git pull
における早送り戦略とは、ローカルブランチの最終コミットよりもリモートブランチのほうが数コミット進んでいることを意味します。
たとえば、ローカルブランチに commit A <- commit B
があり、リモートブランチに commit A <- commit B <- commit C
がある場合、git pull
はリモートブランチから commit C
だけを取得してローカルブランチに追加します。
をローカルブランチに追加します。
この場合、マージは不要なのでマージ処理は中断されず、マージコミットを別に作成する必要もありません。実際に見てみましょう。
出力からわかるように、fast-forward 戦略を使用して git pull
プロセスが自動的に完了しました。
1.2. マージの衝突を解決する必要がある場合
リモートブランチとローカルブランチの間に競合する行がある場合、git pull
は一時停止し、特にマージ処理を中断します。たとえば、リモートブランチとローカルブランチが異なる変更を新たにコミットした場合などです。
この場合は git fetch のみを行い、マージフェーズを終了させる必要があります。マージの衝突を解決する方法は git merge の記事ですでに学んだので、さっそく実行結果を見てみましょう。
ログを見ると、pull 中にマージの衝突があったことがわかります。これを解決してからコミットしました。
2. git fetch との違い
上でも少し触れましたが、git pull
コマンドには git fetch
コマンドも含まれています。
git fetch
コマンドは、現在のブランチが追跡しているリモートブランチの情報をすべて取得して保存します。
リモートブランチは通常 origin/main
という名前の形式で、git branch post で見たように git branch -r
コマンドで見ることができます。
次のコマンドを使います。
$ git fetch [remote-name]
実行結果は次のようになります。
出力を見ると、上の git pull
の出力に表示されているメッセージの一部が fetch
コマンドによるものであることがわかります。
fetch
コマンドを入力したので、次のようにリモートブランチの履歴を取得することもできます。
3. --force オプション
git pull
コマンドで使用できる --force
オプションは、実際には git fetch
コマンドのオプションです。
これは、コミットの削除などによってリモートブランチの履歴とローカルブランチの履歴が一致しない場合に使用します。
このような場合、git fetch
は拒否されますが、--force
オプションを指定すると現在のリモートブランチのコミット履歴をローカルの追跡ブランチで上書きするようになります。
しかし、このオプションはマージフェーズには適用されません。そのため、強制的にフェッチしても現在のブランチとコンフリクトしている場合は、手動でマージのコンフリクトを解決する必要があります。
次のコマンドを使用してください。
$ git fetch --force [remote-name]
または
$ git pull --force [remote-name] [branch-name]
4. --rebase オプション
git pull
コマンドはデフォルトではマージで動作します。
--rebase
オプションは、マージの代わりに git rebase コマンド を実行するように git fetch
に指示します。
マージとリベースの違いは こちら にまとめられています。
rebase による pull は、リモートブランチのコミットをリモートブランチとローカルブランチの共通の先祖にアタッチし、ローカルブランチのコミットをその最後のコミットにアタッチします。 この処理はコミット履歴を変更するので、使用には注意が必要です。
使用するには、次のコマンドを実行します。
$ git pull --rebase <remote-name> <branch-name>
git pull その他のオプション
5.1. --コミットしないオプション
git pull --no-commit
このオプションは git pull
の結果をもう一度確認したい場合や、何らかの操作を追加したい場合に使用します。
このオプションは git pull
の処理をコミットする直前で停止させます。この時点で新しい操作を追加して、手動でコミットして pull コマンドを完了させることができます。
5.2. ff-onlyオプション
git pull --ff-only
このオプションを指定すると、早送りの場合にのみプルを完了させるようになります。このオプションを指定すると、ローカルブランチは偶発的でも変更されず、リモートブランチだけが完全にコピーされることを保証できます。
5.3. -depth オプション
git pull --depth [depth-number]。
このオプションは他の多くのコマンドにも含まれており、必要なコミット数だけをプルすることができます。リモートブランチのコミット履歴全体を必要としない場合は、このオプションを使用するとオーバーヘッドやディスク容量などを節約できます。
5.4. --プルーンオプション
git pull --prune
このオプションは、現在リモートリポジトリに存在しないブランチを追跡しているローカルブランチをクリーンアップするために使用します。リモートリポジトリが真実のソースであるという確信があるのなら、このオプションを使うことでローカルの Git 環境をよりクリーンな状態に保つことができます。
5.5. --autostash オプション
git pull --autostash
このオプションは、現在行っている変更を自動的に隠して一時的に保存し、プルを続行します。保存した変更は、プルが完了した後に自動的に戻ってきます。これはコミットする前にプルする必要がある場合に便利です。
6. 最後に
git pull
コマンドは、リモートとローカルのリポジトリを同期させるための最も重要なコマンドのひとつです。
git pull
コマンドを使う際のトラブルシューティングを簡単に行う方法のひとつは、pull をフェッチ、マージやリベースを別のステップと考えることです。
git merge
コマンドについての詳しい説明は、この記事 を参照ください。
