Skip to content
This page has been auto-translated and may contain errors.View in English

git log、show、diffでGitの履歴を表示する

docs.scrimba.com

weather-appを月曜日の朝に開いて、金曜日に何をリリースしたのか正確に思い出せないことがあります。あるいはチームメイトが先週の気温変換が変わった理由を聞き、推測ではなく本当の答えが必要な場合もあります。コミットループはコミットがどのように保存されるかを説明しています。この章では、その履歴を逆向きに読むことを扱います。何が起きたか、誰がしたか、いつしたか。そのコマンドはgit logで、小規模なプロジェクトで印字されるすべてをここに示します。

bash
$ git log
commit 4f2a1c9d8e7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c
Author: Taro Yamada <[email protected]m>
Date:   Tue Jul 14 09:12:03 2026 +0100

    セルシウス-ファーレンハイト変換式の温度変換を修正

commit 5f3d8b21a90e7c6d5b4a3f2e1d0c9b8a7f6e5d4c
Author: Hanako Sato <[email protected]m>
Date:   Mon Jul 13 16:45:22 2026 +0100

    ダッシュボードに5日間予報を追加

commit 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b
Author: Hanako Sato <[email protected]m>
Date:   Mon Jul 13 11:03:47 2026 +0100

    プロジェクト構造を設定

1つのコマンドで、プロジェクト全体の物語がそこにあります。3つのコミット、新しい順に、それぞれ誰が書いたか、いつか、そして理由が。

git logでログを読む

git logは現在いる場所から到達可能なすべてのコミットを逆方向に歩みます。最新のものが最初です。各エントリは4つのものを表示します。ハッシュ(そのコミットを識別する長い文字列と数字)、作成者、日付、そしてその作成者が書いたメッセージです。

コミットは、これらの4つのものをまとめたもの。その時点でのすべての追跡ファイルのスナップショット、変更を説明するメッセージ、それを誰が作ったか、そして直前のコミット、その親コミットへのリンク。この親リンクが、個別のスナップショットの集まりを実際のタイムラインに変えます。git logを上から下へ読み、タイムラインを逆向きに読んでいます。現在から始まりまで。

ハッシュは最初は威圧的に見えますが、全体が必要なことはめったにありません。4f2a1c9d8e7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c4f2a1c9は同じコミットを指します。Gitは、リポジトリ内の他のすべてのコミットと区別するのに十分なハッシュだけが必要で、最初の7文字程度はほぼ常に十分です。このシンプルな形式は、この章の残りのコマンドを含め、あらゆる場所で見かけます。

デフォルトのgit log出力は詳細ですが、背が高いです。3つのコミットで既にターミナル全体を占めています。いくつかの形状が日常的により有用にします。

bash
$ git log --oneline
4f2a1c9 セルシウス-ファーレンハイト変換式の温度変換を修正
5f3d8b2 ダッシュボードに5日間予報を追加
1a2b3c4 プロジェクト構造を設定

--onelineは各コミットを短いハッシュとメッセージに折りたたみ、コミットあたり1行にします。これは最も多く使う形式です。--graphは歴史の形状をログの横に、線と点の集合として描きます。まだブランチがないプロジェクトでは、単純な直線を描きますが、早期から指に入れておきましょう。ブランチが現れる瞬間(次の章)が、この図がその価値を示し始める時です。

ログをスクロールする代わりにフィルタすることもできます。git log --author="Hanako"はHanakoによって書かれたコミットだけを表示し、共有プロジェクトで1人の仕事を見たいときに便利です。git log -- src/index.jsはその特定のファイルに触れたコミットだけを表示し、それに決して近づかなかったものは無視します。

bash
$ git log --oneline -- src/index.js
4f2a1c9 セルシウス-ファーレンハイト変換式の温度変換を修正
1a2b3c4 プロジェクト構造を設定

2番目のコミット、予報のもの、src/index.jsに触れませんでした。それで表示されません。両方のフィルタは--onelineと一緒にきれいに組み合わさります。

上記のフィルタは「このファイルに触れたコミットはどれか」に答えます。悪い日に実際に履歴に送り込むより鋭い質問は。このコードの正確な部分がいつ現れたか、または消えたか?これが**ピッケル**として知られているgit log -Sの目的です。文字列を与え、その文字列の発生数が変わったコミットだけを保ちます。つまり、それを追加または削除したコミット。

bash
$ git log --oneline -S "showLoadingSpinner"
7d1e8c3 予報データの読み込み中にローディングスピナーを追加

历史全体のうちの1つのコミット。その呼び出しがコードベースに入った瞬間。これは、何もチェックアウトせずに「このバグ行がいつ導入されたのか」という質問に答える最速の方法です。数え方の規則には知る価値のある1つの結果があります。ファイル内の行のみを移動するコミットは、発生数を変えないままにするため、-Sはそれをスキップします。どのコミットのdiffが移動を含むテキストに触れるかが必要な場合、代わりにgit log -Gを正規表現で使用します。最初に-Sに到達します。通常は、より鋭いツールです。

Junoログを読むgit logはすべてのコミットを最新順に表示し、ハッシュ、作成者、日付、メッセージを含みます。コミットはそのスナップショットとメッセージと、その前のコミットへのリンクです。完全なハッシュが必要になることはめったになく、最初の数文字でGitは正確にどのコミットを意味するのかを知っています。
Junoログを読むgit log --onelineは毎日使う形式で、コミットあたり1行です。--authorや末尾の-- pathを追加して1人の仕事や1つのファイルの履歴をフィルタし、ブランチが登場したら--graphに到達します。
Junoログを読む すべてのコミットのハッシュは独自の内容とその親のハッシュの指紋なので、2つのコミットが誤って衝突することはなく、短いプレフィックスを入力するのは安全です。そして質問が「この行がいつ現れたか消えたか」であれば、git log -S "text"は全履歴を歩み、それを追加または削除したコミットのみを保ちます。親リンクとの組み合わせで、この章は私のデバッグツールキットのほとんどです。

git showで1つのコミットを検査する

git logはコミットが起きたことを教えます。git show <hash>はそれが正確に何をしたかを教えます。

bash
$ git show 4f2a1c9
commit 4f2a1c9d8e7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c
Author: Taro Yamada <[email protected]m>
Date:   Tue Jul 14 09:12:03 2026 +0100

    セルシウス-ファーレンハイト変換式の温度変換を修正

diff --git a/src/index.js b/src/index.js
index 3f2c1a9..7b8e2d4 100644
--- a/src/index.js
+++ b/src/index.js
@@ -12,7 +12,7 @@ function celsiusToFahrenheit(celsius) {
-  return celsius * (9 / 5 + 32)
+  return (celsius * 9) / 5 + 32

上部はgit logが表示するのと同じメタデータです。その下は実際の変更。-で始まる行はコミットが削除した行、+で始まる行はそれが追加した行、マークされていない行は同じままのコンテキストです。ここではっきり読めます。古い行は32を括弧の中でグループ化しているため、乗算の前に追加されていました。修正は括弧をcelsius * 9の周りに再グループ化して、32が最後に追加されるようにします。Taroのメッセージがについて説明する演算子優先度のバグです。

パスを追加して、より大きなコミットの一部のみを見ます。git show 4f2a1c9 -- src/index.jsは、1つのコミットが複数のファイルに触れ、その中の1つだけが必要な場合に重要です。

Juno1つのコミットを検査するgit show <hash>は1つのコミットを完全に表示します。誰がそれを作ったか、いつ、そして変更した実際の行。削除された行はマイナス記号で始まり、追加された行はプラス記号で始まります。「このコミットは実際に何をしたか」という質問に答える最速の方法です。
Juno1つのコミットを検査するgit show <hash>は1つのコミットのメタデータと完全なdiffを表示します。特定のパスを指すこともできます。git show <hash> -- path/to/file。コミットが複数のファイルに触れ、1つのファイルのスライスだけが必要な場合です。
Juno1つのコミットを検査するgit showはコミットの保存されたスナップショットを親のスナップショットと比較し、異なる行のみを印字しています。このようにdiffを読み始めると、コミットは謎の箱から、差分のある2つのスナップショットになります。

git diffが表示するもの、そしてほぼ全員がぶつかる勘違い

git loggit showはコミットされた履歴を読みます。git diffはまだコミットされていないもの、つまり今のワーキングディレクトリにある変更を読みます。これを最後のコミットと比較します。

bash
$ git diff
diff --git a/README.md b/README.md
index 1c2d3e4..9f8a7b6 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
 # weather-app
+Vanilla JavaScriptで構築された5日間の天気ダッシュボード。

これはREADME.mdへの編集で、ステージまたはコミットする前に示されています。ここが最初の1週間でほぼ全員を捕まえる部分。git add .を実行してその変更をステージし、その後git diffを再度実行すると、まったく何も表示されません。

bash
$ git add .
$ git diff

何も印字されていません。編集は消えていません、何も間違っていません。平文のgit diffはワーキングディレクトリとステージングエリアを比較しており、すべてをステージしたら、その2つは今一致しているため、そこに左に表示される差分は残りません。ステージングエリアで待機中の変更を見るには、代わりにgit diff --stagedを使用します。

bash
$ git diff --staged
diff --git a/README.md b/README.md
index 1c2d3e4..9f8a7b6 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
 # weather-app
+Vanilla JavaScriptで構築された5日間の天気ダッシュボード。

同じ変更、今見えます。なぜなら--stagedはステージングエリアを最後のコミットと比較しているからです。

平文のgit diffgit diff --stagedは2つの異なる質問に答えており、正確に名前を付けるのが役に立ちます。平文のgit diffはワーキングディレクトリをステージングエリアと比較します。これはステージしていない編集を表示します。git diff --stagedはステージングエリアを最後のコミットと比較します。今すぐgit commitを実行したときに次のコミットに入るものを正確に表示します。どちらもその場で両方を表示することはなく、これはちょうど完全にステージされた変更が平文のgit diffを静かにする理由です。あなたは時々--cachedを古いチュートリアルとドキュメントで見かけます。それは--stagedと同じことを意味します。

コミットする前に両方を実行することは良い習慣です。平文のgit diffは重要なものが未ステージのままになっていないことを確認し、git diff --stagedは正確に何が保存されるかを確認します。

Juno何が変わったかを見るgit diffはまだステージされていないワーキングディレクトリ内の編集を表示します。git addですべてをステージすると、平文のgit diffは静かになります。これは期待されています。変更はまだそこにあります。git diff --stagedを使用して、コミットされるのを待っているものを見ます。
Juno何が変わったかを見る 平文のgit diffはワーキングディレクトリとステージングエリア、git diff --stagedはステージングエリアと最後のコミット、2つの異なる比較です。コミットする前に両方を実行すると、未ステージのものと保存されるものが何であるかがわかります。古い資料は時々--cachedを言い、同じフラグ、異なる名前。
Juno何が変わったかを見る 両方のdiffは異なるスナップショットペアに適用される同じ操作です。ワーキングツリーとステージングエリア、またはステージングエリアと最後のコミット。比較する2つのものがどれであるかを名前付けることは、空のgit diffによって混乱しないための全体的なトリックです。

なぜGit履歴がグラフを形成するのか

これまで見たすべてのコミットは正確に1つの親を指し、git logを上から下へ読むことは直線を読むように感じています。これはソロプロジェクトで1行の作業をしている限り保ちます。ブランチとマージが登場し、次のブランチでカバーされます。プロジェクトの実際の履歴は分割されて別の行に分け、一緒に戻すことができるからです。

これは以前の--graphフラグが実際に行うことです。weather-appでは現在、1つのコミット行しかないため、単一の列を描きます。ブランチが分岐し、後で合併されると、--graphは分岐と再結合を、フラットなハッシュのリストから画像を描こうとするよりはるかに読みやすい別の列として描き始めます。

マージコミットでgit showを実行し、デフォルトでは、メタデータのみを印字します。diffはまったくありません。-mを追加して、各親の順番に別のdiffを印字します。両方の動作は同じ形状に戻ります。Gitの履歴は**DAG**、有向非環グラフです。「有向」はすべてのリンクが一方向を指すこと、コミットを親に指す、決して前に指さないことを意味します。「非環」はそれらのリンクが決してループしないこと、それらを歩むことは常にプロジェクトの開始に向かって、あなたが既に通過したコミットに決して戻らないことを意味します。通常のコミットは正確に1つの親を持ち、これはソロプロジェクトのログが直線として読む理由です。マージコミットは例外です。1つではなく2つの親ハッシュを持ちます。2つの親では、平文のgit showには、-mが各親とを比較するよう指示するまで、印字する単一の「diffです」がありません。ブランチと合併、次の2つの章は、この同じグラフに直接構築されます。

Junoグラフとしての履歴 現在、見たすべてのコミットが1つの親を指しているため、ログは直線のように読みます。ブランチが分割されて一緒に合併されると、次に会うとき、それが変わります。基礎となる形状、コミットが前のコミットにリンクされている、これすべてを可能にします。
Junoグラフとしての履歴 単一のコミット行は、それぞれが1つの親を持っているため、直線のように見えます。--graphフラグは、分岐が始まると形状を見えるようにします。フラットなリストの代わりに分岐と合併を描きます。それが必要になる前に、あなたのツールキットに保ちます。
Junoグラフとしての履歴 Gitの履歴は有向非環グラフです。親ポインタは決して逆向きのみを指し、決してループしません。マージコミットは、1つではなく2つの親を取得するコミットの唯一の場所です。これが平文のgit showが親を選ぶために-mを追加するまでそこに差分を印字しない理由です。ブランチと合併はこの同じグラフの残りの部分を異なる角度から教えます。