プッシュとプルとは?ローカルとリモートのリポジトリをそろえる仕組み

Gitの版:2.56.0
コミットしただけでは、変更は自分のパソコンの中に記録されたにすぎません。ほかの人と共有するには、リモートのリポジトリへ送る必要があります。手元とリモートの間でコミットを受け渡す操作が、プッシュとプルです。
本記事では、Gitの公式ドキュメントと『Pro Git』をもとに、プッシュ、プル、フェッチの違いと、プッシュが断られる場面を解説しましょう。
プッシュとプルとは
プッシュ(push)は、ローカルリポジトリにあってリモートにないコミットを、リモートリポジトリへ送る操作です。プル(pull)はその反対で、リモートにあって手元にないコミットを受け取り、作業中のブランチに取り込みます。
この2つを繰り返せば、複数の人がそれぞれの手元で作業しながら、同じリポジトリの履歴をそろえていけるのです。
プッシュ・フェッチ・プルの違い
受け取る側の操作には、プルのほかにフェッチ(fetch)もあります。
フェッチは、リモートの新しいコミットを手元のリポジトリに受け取るだけの操作です。『Pro Git』の説明では、フェッチは自分の作業に自動で統合したり、作業中のものを変えたりしません。受け取った内容を確かめてから、自分で統合できます。
一方のプルは、フェッチしたうえで、作業中のブランチに統合するところまでを一度に行う操作です。手軽な反面、受け取った変更がすぐに自分の作業へ統合される点に気をつけてください。
| 操作 | 向き | 作業中のブランチ |
|---|---|---|
| プッシュ | 手元 → リモート | 変わらない |
| フェッチ | リモート → 手元 | 変わらない |
| プル | リモート → 手元 | 受け取った変更が統合される |
プッシュが断られるとき
プッシュは、いつでも成功するわけではありません。よくあるのは、自分がプッシュする前に、ほかの人が同じブランチへ先にプッシュしていた場面です。
このとき、手元にはほかの人のコミットBがありません。そのまま自分のコミットXで上書きすると、Bが履歴から失われてしまいます。Gitのドキュメントによると、git push が更新を許すのは、何も指定しなければ、リモートの先端が自分の送るコミットの祖先になっている場合(早送りできる場合)だけです。リモートのデータを誤って失わないための安全装置といえます。
断られたら、まずプルかフェッチでほかの人のコミットを受け取り、自分の作業と統合してから、もう一度プッシュしてください。書き込みの権限がないリポジトリへのプッシュも、同じように断られます。
強制的なプッシュに注意する
この確認を外して上書きする指定が、git push の --force です。Gitのドキュメントは、リモートのコミットを失わせるおそれがあるため、注意して使うよう書いていました。
上の例で --force を使うと、ほかの人のコミットBはどのブランチからもたどれなくなり、やがてリモートから消えてしまいます。共有しているブランチでは、基本的に使わないようにしましょう。
どうしても上書きが必要なときのために、--force-with-lease という指定も用意されています。リモートが自分の知らないうちに変わっていないかを確かめてから上書きする、より安全な方法です。
製品での使われ方
プッシュとプルはGitそのものの機能で、GitHubやGitLabなどのどのサービスでも同じように使います。
プッシュは、リモートを通してほかの人に変更が届く操作です。サービスによっては、プッシュをきっかけにサイトの公開などが自動で始まります。本サイトの「【Cloudflare】GitHubのリポジトリとつないでサイトを公開する方法」も、その一例です。
プログラミング用のAIエージェントにGitの操作を任せるなら、プッシュの扱いを先に決めておきましょう。コミットまでは任せ、プッシュは人が指示したときだけにするのも1つの方法です。製品の権限の設定を使えば、git push の前に確認を求めたり、--force を拒否したりできます。