◀ 18.

【git】リモートとローカルの差分表示

▶
この記事の要点
  • リモートとの差分を見る前に、必ず git fetch でリモートの最新状態を取得する
  • コミット済みの内容の差分: git diff HEAD origin/main
  • リモート側で増えた変更だけ見る: git diff HEAD...origin/main(ドット 3 つ)
  • 未 pull / 未 push のコミット一覧: git log HEAD..origin/main / git log origin/main..HEAD
  • git diff HEAD だけでは「作業中の変更」しか見えず、リモートとは比較されない
  • ファイル名だけなら --name-only、件数の概要なら --stat

結論:fetch してから origin/ブランチ名と比較する

ローカルリポジトリで次の 2 行を実行すると、リモートリポジトリの最新状態とローカルのコミットの差分を表示できます(ブランチ名が master の場合は origin/master に読み替えてください)。

git fetch origin
git diff HEAD origin/main

よく紹介される git diff HEAD は、最新コミット(HEAD)と作業ツリーの差分、つまり「まだコミットしていない自分の変更」を表示するコマンドです。リモートとの比較にはならないので注意してください。

なぜ fetch が必要なのか(仕組み)

Git はリモートの状態を、ローカルに リモート追跡ブランチ(origin/main など)として保存しています。git diff や git log はネットワークに接続せず、このローカルのコピーを見て比較します。

  • git fetch: リモートの最新コミットを取得して origin/main を更新する。作業ツリーやローカルブランチは変更しないので安全
  • git pull: fetch に加えてマージ(または rebase)まで行う。差分を確認したいだけなら使わない

fetch しないまま比較すると、前回 fetch した時点の古いリモート状態と比べることになります。

目的別のコマンド

知りたいことコマンド
ローカルとリモートのコミット内容の違い(全体)git diff HEAD origin/main
リモートで増えた変更だけ(pull すると入ってくる内容)git diff HEAD...origin/main
自分が push していない変更だけgit diff origin/main...HEAD
作業中(未コミット)の変更も含めてリモートと比較git diff origin/main
未 pull のコミット一覧git log --oneline HEAD..origin/main
未 push のコミット一覧git log --oneline origin/main..HEAD
特定のファイルだけgit diff HEAD origin/main -- path/to/file

ドット 2 つと 3 つの違い

git diff A B(git diff A..B と同じ)は、A と B の 2 つのスナップショットをそのまま比較します。ローカルとリモートの両方に新しいコミットがある場合、双方の変更が混ざって表示されます。

git diff A...B は、A と B の共通の祖先から B までの変更だけを表示します。「リモートで誰かが何を変えたか」だけを見たいときはこちらが分かりやすくなります。

なお git log ではドット 2 つ A..B が「B にあって A にないコミット」という意味になり、diff とは意味が異なります。

差分の見せ方を変えるオプション

# 変更されたファイル名だけ
git diff --name-only HEAD origin/main

# ファイル名と変更種別(A=追加, M=変更, D=削除)
git diff --name-status HEAD origin/main

# ファイルごとの増減行数の概要
git diff --stat HEAD origin/main

# 単語単位で差分を表示(文章の修正確認に便利)
git diff --word-diff HEAD origin/main

上流ブランチを使った短い書き方

ローカルブランチに上流(upstream)が設定されていれば、@{u}(@{upstream})でリモート追跡ブランチを指定できます。ブランチ名を毎回打たずに済みます。

git fetch
git diff HEAD @{u}
git log --oneline HEAD..@{u}

# ahead / behind のコミット数を数える(左: ローカルのみ, 右: リモートのみ)
git rev-list --left-right --count HEAD...@{u}

上流が設定されていない場合は「no upstream configured」というエラーになります。git branch -u origin/main で設定できます。

確認方法:git status で ahead / behind を見る

fetch した後の git status には、リモートとの関係が 1 行で表示されます。

Your branch is behind 'origin/main' by 3 commits, and can be fast-forwarded.
  • behind: リモートに未取り込みのコミットがある(pull が必要)
  • ahead: ローカルに未 push のコミットがある
  • have diverged: 両方に新しいコミットがある(マージか rebase が必要)
  • up to date: 最後の fetch 時点では一致している

よくある質問

差分が何も表示されないのに、リモートには変更があるはず

fetch をしていない、または比較しているブランチ名が違う(main と master、別名のブランチなど)可能性があります。git branch -r でリモート追跡ブランチの一覧を確認してください。

差分を GUI で見たい

git difftool HEAD origin/main で、設定した比較ツール(VS Code など)を起動できます。Sourcetree などの Git クライアントでも、fetch 後に両ブランチを選択して比較できます。

確認したらローカルをリモートに合わせたい

通常は git pull で取り込みます。ローカルの変更を捨ててリモートと完全に同じにしたい場合は、別記事「ローカルをリモートリポジトリの状態に戻す」の手順を参照してください。

関連

Post Share
子ページ

子ページはありません

同階層のページ
  1. 用語一覧
  2. エラー一覧
  3. git本体のインストール(Linux)
  4. Linuxサーバーへのgit導入とクライアントのセットアップ
  5. リモートリポジトリをローカルリポジトリとしてクローンする方法
  6. リモートとローカルのリポジトリを同期(pull)する方法
  7. 設定の確認
  8. gitユーザー名とemailの設定
  9. リモートリポジトリの作成
  10. ローカルリポジトリの作成
  11. 新規ファイル/ディレクトリをインデックスに登録
  12. インデックスの登録状態を確認
  13. ローカルリポジトリの変更をコミット
  14. コミット履歴の確認
  15. クライアントからリモートリポジトリの接続設定、確認、削除
  16. リポジトリへのプッシュ
  17. リモートリポジトリからクライアントへのSSHクローン
  18. リモートとローカルの差分表示
  19. バージョンの確認
  20. プロキシの設定
  21. ローカルをリモートリポジトリの状態に戻す
  22. ブランチの作成, 一覧表示, 切り替え
  23. ブランチのマージと削除
  24. リベース
  25. .gitignoreの書き方
  26. .gitignoreの設定が反映されない場合
  27. 特定のファイルをgitの管理から外す方法
  28. 参照(ORIG_HEAD, HEAD, FETCH_HEAD)
  29. git rm [-r --cached] の取り消し
  30. 一部のディレクトリ/ファイルのみをリポジトリから復元する方法
  31. ローカルとリモートリポジトリの有無を同期
  32. pushの取消し方法
  33. マージツールの起動方法
  34. Gitで「MERGING」の状態