【Git基礎】なぜ pull してから作業するのか? 衝突を防ぐリモート連携のルール

READMEを修正してコミットしたのに、GitHubの画面では説明が変わっていない。逆に、ほかの人がGitHubへ送った修正が、自分のパソコンにはまだ見えていない。

この違いを理解するには、「手元のリポジトリ」と「共有先のリポジトリ」を分けて考えることが大切です。コミットは手元に変更を記録する操作です。共有先と履歴をやり取りするときに、pushやpullを使います。

この記事では、GitHubを共有先にした練習例で、送る方向・取り込む方向と、基本的な確認手順を説明します。GitとGitHubの公式資料に基づく入門記事です。

目次

1. 手元と共有先には、それぞれ履歴がある

Gitで管理するプロジェクトは、手元のパソコンだけでもコミットできます。GitHubへ送っていないコミットが、手元に存在することもあります。

一方、チームの人が共有先を更新しても、手元のファイルが常に自動更新されるわけではありません。必要なタイミングで共有先の情報を取得します。

この共有先を、Gitでは「リモート」と呼びます。GitHubはリモートの置き場所として使えるサービスの1つです。リモートには名前を付けて扱い、cloneしたリポジトリでは通常、元の取得先にoriginという名前が付きます。Git公式:リモートの操作

originはURLそのものではなく、接続先を示す名前です。名前も接続先も、プロジェクトによって違う場合があります。

2. commit・push・fetch・pullの役割

4つの操作を、役割で分けてみましょう。

操作 主な役割 向きのイメージ
commit 選んだ変更を手元の履歴へ記録する 作業内容から、手元の履歴へ
push 手元の履歴を送り、共有先のブランチなどを更新する 手元から共有先へ
fetch 共有先の履歴や参照の情報を取得する 共有先から手元へ取得
pull 取得に続いて、現在のブランチへ履歴を取り込む 共有先から手元へ取得・統合

pushで送る中心となるのは、コミット済みの履歴です。ファイルを保存しただけ、あるいはステージングしただけの編集を、そのまま送る操作ではありません。Git公式:git push

fetchは情報を取得しますが、通常、それだけで現在の作業ブランチや編集中のファイルを更新しません。Git公式:git fetch

pullは取得と取り込みをまとめた操作です。取り込み方には、履歴をまとめるmerge、手元のコミットを並べ直すrebase、分岐していない場合だけ進めるfast-forwardなどがあり、オプションや設定によって動きが変わります。Git公式:git pull

「pullは単にファイルをダウンロードすること」と考えず、現在のブランチを更新する操作として扱いましょう。

commit・push・fetch・pullの向きと役割
選んだ作業内容commit:手元の履歴へ記録
→
手元の履歴・現在のブランチ
手元の履歴・現在のブランチpush:コミット済みの履歴を送り、共有先を更新
→
共有先の履歴・ブランチ
共有先の履歴・ブランチfetch:情報を取得。通常、現在の作業ブランチは更新しない
→
手元に取得した共有先の履歴や参照の情報
共有先の履歴・ブランチpull:取得に続いて現在のブランチへ取り込む
→
手元の履歴・現在のブランチ

3. 操作する前に、接続先とブランチを確認する

まず、次の2つを確認します。

git remote -v
git status

git remote -vでは、リモートの名前とURLを確認できます。目的のGitHubリポジトリか、fetchとpushの接続先がどこかを見ます。Git公式:リモートの確認

git statusでは、作業中のブランチと未コミットの変更を確認します。取り込み前には、必要な編集をコミットするか、一時退避するなどして、作業の区切りをつけておくと判断しやすくなります。

認証エラーの場合は、履歴の問題と分けて考えます。GitHubとの通信では、HTTPSやSSHなど、接続方式に合った認証が必要です。また、送信先への書き込み権限も必要です。GitHub公式:認証について

接続先、現在のブランチ、未コミットの編集。この3つを確認してから操作しましょう。worktreeを使っている場合は、開いている作業フォルダーも確かめます。

4. 共有先のmainを、手元のmainへ取り込む

ここからは、GitHubからclone済みの練習用リポジトリを想定します。originが目的の共有先を指し、手元と共有先にmainが存在し、未コミットの変更がないものとします。

git switch main
git pull --ff-only origin main
git status

この例では、手元のmainへ切り替えてから、originのmainを取り込みます。--ff-onlyは、手元と共有先の履歴が分岐している場合に、取り込みを失敗させる指定です。自動でマージコミットを作ったり、手元のコミットを並べ直したりせず、履歴を進められる場合に更新します。Git公式:pullの取り込み方法

失敗した場合は、メッセージを読み、履歴が分かれた理由を確認します。チームの方針に合わせてmergeやrebaseを選ぶ場面ですが、意味を確認せず別のオプションを足さないようにしましょう。

また、git pull origin mainは「どこで実行しても手元のmainを更新する」コマンドではありません。現在のブランチへoriginのmainを取り込みます。修正用ブランチで実行すれば、その修正用ブランチへの取り込みになります。

5. 修正用ブランチを作って、コミットを送る

続いて、READMEの保存先の説明を直す練習例です。新しいブランチ名feature/readme-guideは、まだ存在しないものとします。

手順1:作業するブランチを作る

git switch -c feature/readme-guide

前の節で更新したmainから、README修正用の作業を分けます。

手順2:編集・確認・コミットを行う

READMEを修正して保存したら、変更の中身を確認して記録します。

git diff
git add README.md
git diff --staged
git commit -m "READMEの原稿保存先を修正"
git status

ここまでは手元の操作です。すでに別の変更がステージングされている場合は、それもコミットに入るため、記録予定の差分を見直してください。

手順3:修正用ブランチを共有先へ送る

git push -u origin feature/readme-guide

この例では、手元の修正用ブランチをoriginの同名ブランチへ送ります。-uは、成功した送信先のブランチを、手元のブランチの追跡先として設定する指定です。Git公式:pushと追跡先の設定

送信が成功したら、GitHubで目的のブランチとコミットを確認します。mainへ変更を取り込む場合は、Pull Requestやレビューなど、チームで決めた手順に従います。

修正用ブランチをpushしても、それだけでmainへマージされるわけではありません。また、Webサイトの公開が自動で始まるかどうかは、接続された公開処理の設定によります。

README修正を共有先へ送る手順
  1. 前の節で更新した手元のmain
    git switch -c feature/readme-guide ↓
  2. feature/readme-guideを新しく作る
    修正用ブランチで作業 ↓
  3. READMEを修正して保存
    変更の中身を見る ↓
  4. git diffで変更を確認
    記録する変更を選ぶ ↓
  5. git add README.mdでステージング
    別の変更も含まれていないか見直す ↓
  6. git diff –stagedで記録予定の差分を確認
    確認した変更を記録 ↓
  7. git commitで手元に記録し、git statusで確認
    コミット済みの履歴を送る ↓
  8. git push -u origin feature/readme-guide
    送信成功後に確認。成功した送信先を追跡先に設定 ↓
  9. GitHubで目的のブランチとコミットを確認
    mainへ変更を取り込む場合 ↓
  10. mainへの取り込みは、Pull Requestやレビューなどチームの手順に従う

6. pushを拒否されたときは、理由を読む

共有先に、手元がまだ持っていないコミットがあると、pushが「non-fast-forward」などの理由で拒否されることがあります。共有先の履歴を失わないために、Gitが更新を止めている状態です。GitHub公式:non-fast-forwardエラー

たとえば、同じ修正用ブランチへ別の人が先にコミットを送った場合です。次の順で状況を確認すると整理しやすくなります。

  1. エラーメッセージを読む。
  2. 送信先とブランチ名が合っているか確認する。
  3. 共有先の変更を取得し、手元との履歴の関係を確認する。
  4. チームの方針に従って変更を取り込み、内容を確認してから再送する。

取り込み中に同じ箇所の変更が競合すると、コンフリクトの確認と修正が必要になる場合があります。強制pushは、共有先の履歴を書き換えるおそれがある操作です。通常の更新が拒否された理由を、強制で解消しようとしないことが大切です。

なお、すべての拒否が履歴の食い違いとは限りません。認証、権限、ブランチの保護ルールなど、表示された理由に応じて確認します。

pushが拒否されたときの確認と対応
エラーメッセージを読むまず接続先を確認
→
送信先とブランチ名を確認
送信先とブランチ名を確認non-fast-forwardなど履歴の関係を確認する場合
→
共有先の変更を取得し、手元との履歴の関係を確認
共有先の変更を取得し、手元との履歴の関係を確認履歴の関係とチームの方針を踏まえる
→
チームの方針に従って変更を取り込む
チームの方針に従って変更を取り込む同じ箇所の変更が競合した場合
→
コンフリクトを確認・修正
コンフリクトを確認・修正必要な修正後
→
取り込んだ内容を確認
チームの方針に従って変更を取り込む競合なく取り込めた場合
→
取り込んだ内容を確認
取り込んだ内容を確認内容を確認してから
→
再送する
送信先とブランチ名を確認認証・権限・保護ルールなどが拒否理由の場合
→
表示された理由に応じて認証・権限・ブランチの保護ルールなどを確認

7. fetchで取得してから、差分を確認する

共有先の変更を、取り込む前に見たい場合は、fetchと確認を分けて行えます。

git fetch origin
git diff HEAD origin/main

この例は、現在のHEADの状態と、取得後のorigin/mainの状態を比較します。手元のmainと比較したい場合は、main上で実行するか、比較対象を明示してください。未コミットの編集を比べるコマンドではありません。

origin/mainは、手元にある「originのmainを追跡する参照」です。GitHub上の状態を常に直接読んでいるわけではないため、確認前にfetchして情報を更新します。Git公式:リモートブランチ

ここで見えるのは、2つのコミットの状態の違いです。コミットの順番や履歴が分岐しているかも確認したい場合は、履歴の表示を併用します。

fetchで取得して確認することと、pullで現在のブランチへ取り込むこと。この違いを覚えておくと、操作の範囲を判断しやすくなります。

8. まとめと理解度確認

commitで手元に記録し、pushで共有先へ送ります。共有先からは、fetchで情報を取得し、pullでは取得に続いて現在のブランチへの取り込みまで行います。

操作の前には、接続先、現在のブランチ、作業中の変更を確認しましょう。成功したかどうかは、表示された結果と、手元・GitHub双方の状態で確かめます。

自分の言葉で説明してみる

  1. コミットしただけで、GitHubにも変更が反映されますか?
  2. pushの向きは、手元から共有先、共有先から手元のどちらですか?
  3. fetchとpullは、何が違いますか?
  4. 修正用ブランチでgit pull origin mainを実行すると、どのブランチへ取り込みますか?
  5. pushが拒否されたら、すぐ強制pushすればよいですか?

解答例

  1. 反映されません。通常、GitHubへ送るにはpushが必要です。
  2. 手元から共有先です。コミット済みの履歴を送り、共有先を更新します。
  3. fetchは情報を取得する操作で、pullは取得に続いて現在のブランチへ取り込みます。
  4. 現在の修正用ブランチへ取り込みます。手元のmainを更新したいなら、mainへ切り替えてから操作します。
  5. いいえ。まず理由を読み、接続先・権限・履歴などを確認します。

参考資料

資料確認日:2026年10月11日

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次