Git: Gitの差分比較と変更分析
変更点の比較は、コードの変更内容を理解するための重要な手段です。異なるバージョン間の変更点を比較することで、何が変更されたのか、なぜ変更されたのか、そして変更の範囲を明確に把握することができます。
1. 差異の比較に関する基礎知識
(1) Gitの3つの領域
Git には 3 つの重要な領域があり、これらを理解することが diff をマスターするための鍵となります:
graph TB
A[Workspace<br/>Working Directory] -->|git add| B[Buffer<br/>Staging Area]
B -->|git commit| C[Repository<br/>Repository]
A -.->|git diff| B
B -.->|git diff --staged| C
A -.->|git diff HEAD| C
style A fill:#fff3cd
style B fill:#d4edda
style C fill:#c3e6cb
- 作業ディレクトリ:実際にファイルが編集されるディレクトリ
- ステージング領域:コミットの準備が整った変更(ステージング領域とも呼ばれる)
- リポジトリ:すべてのコミットの履歴
(2) 差異を比較するためのシナリオ
- 投稿前の確認:投稿したい内容を確認してください
- コードレビュー:他の人の変更内容をレビューする
- バージョン比較:異なるバージョン間の違いを比較する
- ブランチの比較:異なるブランチ間の違いを比較する
- 紛争分析:紛争の原因を理解する
(3) diff コマンドの概要
git diff 差異を表示するために使用します。基本的な使い方:
BASH
git diff [options] [<commit>] [--] [<path>...]
2. 3つの地域の比較
(1) 作業ディレクトリと一時ディレクトリの違い
作業ディレクトリとステージング領域、つまりステージングされていない変更点との違いを比較してください。
▶ サンプル:ステージングされていない変更の確認
BASH
# Edit File
echo "new line" >> README.md
# View Workspace Changes(Relative to the temporary storage area)
git diff
# Output:
# diff --git a/README.md b/README.md
# index abc1234..def5678 100644
# --- a/README.md
# +++ b/README.md
# @@ -1,3 +1,4 @@
# # My Project
#
# ## Features
# +new line
# View a Specific File
git diff README.md
# View Multiple Files
git diff file1.js file2.js
(2) ステージングエリアとリポジトリ
ステージング領域とリポジトリの違い、つまり、ステージングはされているがまだコミットされていない変更点を比較します。
▶ サンプル:ステージングされた変更を表示する
BASH
# Add or modify to the staging area
git add README.md
# View changes in the staging area(Compared to the latest submission)
git diff --staged
# Or use the old syntax
git diff --cached
# Output:
# diff --git a/README.md b/README.md
# index abc1234..def5678 100644
# --- a/README.md
# +++ b/README.md
# @@ -1,3 +1,4 @@
# # My Project
#
# ## Features
# +new line
(3) 作業ディレクトリとリポジトリの違い
作業ディレクトリとリポジトリの違い、つまりコミットされていないすべての変更点を比較します。
▶ サンプル:保存されていない変更をすべて表示する
BASH
# View the workspace relative toHEADthe differences
git diff HEAD
# View the differences between the workspace and a specific commit
git diff a1b2c3d
# View the differences in the workspace compared to the last commit
git diff HEAD^
# The output includes all changes, both staged and unstaged.
3. 差分の出力の解釈
(1) diff の出力形式
▶ サンプル:diff 出力の理解
BASH
git diff
# Output Format Description:
# diff --git a/file.js b/file.js <- GitDifferential Head
# index abc1234..def5678 100644 <- File Mode
# --- a/file.js <- Original Document(-Indicates deletion)
# +++ b/file.js <- New Document(+Indicates addition)
# @@ -1,3 +1,4 @@ <- Change Location (hunk header)
# # My Project <- Context Line(Starts with a space)
#
# ## Features <- Context Line
# +new line <- Add a row(+Introduction)
# -old line <- Delete Row(-Introduction)
(2) ハンク・ヘッダーの形式
ハンクヘッダー形式: @@ -a,b +c,d @@
-a,b: 元のファイルは a 行目から始まり、合計 b 行あります+c,d: 新しいファイルはc行目から始まり、合計d行あります
TEXT
📖 参照専用
@@ -10,5 +10,7 @@ function login() {
つまり、元のファイルの10行目から始まる5行が、新しいファイルの10行目から始まる7行になったということです。
(3) 統計情報
▶ サンプル:統計情報の概要を表示する
BASH
# Display Statistics
git diff --stat
# Output:
# README.md | 1 +
# file1.js | 5 ++---
# file2.js | 3 +++
# 3 files changed, 5 insertions(+), 3 deletions(-)
# Show brief statistics
git diff --shortstat
# Output:
# 3 files changed, 5 insertions(+), 3 deletions(-)
# Display Numerical Statistics
git diff --numstat
# Output:
# 1 0 README.md
# 2 3 file1.js
# 3 0 file2.js
4. 異なるバージョンの比較
(1) 2つのコミットを比較する
▶ サンプル:提出物の比較
BASH
# Compare the two commits
git diff a1b2c3d d4e5f6g
# Compare a commit to the current workspace
git diff a1b2c3d
# Compare a commit to the staging area
git diff --staged a1b2c3d
# Compare Adjacent Commits
git diff HEAD^ HEAD
# View the changes introduced by a specific commit
git show a1b2c3d
# Equivalent to
git diff a1b2c3d^ a1b2c3d
(2) ブランチの比較
▶ サンプル:ブランチの比較
BASH
# Compare Two Branches
git diff main feature
# ViewfeatureBranch relative tomainChanges to
git diff main...feature
# ViewmainBranch relative tofeatureChanges to
git diff feature...main
# Compare a specific file across branches
git diff main feature -- file.js
# View changes made after the branch was forked
git diff $(git merge-base main feature) feature
(3) 比較タグ
▶ サンプル:バージョンの比較
BASH
# Compare the Two Versions
git diff v1.0.0 v2.0.0
# View the changes in a specific version
git diff v1.0.0 HEAD
# View the release notes
git diff v1.0.0 v2.0.0 --stat
# Output:
# src/auth.js | 25 +++++++++++++++++++++++++
# src/user.js | 10 +++++-----
# package.json | 2 +-
# 3 files changed, 32 insertions(+), 5 deletions(-)
5. diff オプションの詳細な説明
(1) 一般的なオプション
| オプション | 説明 | 目的 |
|---|---|---|
--staged |
ステージングエリアとリポジトリ | ステージングされた変更を表示 |
--stat |
統計を表示 | 統計の表示・編集 |
--shortstat |
概要統計 | 変更の全件を表示 |
--name-only |
ファイル名のみ表示 | 変更されたファイルの一覧を表示 |
--name-status |
表示ステータス | ファイルの変更履歴を表示 |
-w |
空白を無視 | スペースとタブの区別を無視 |
▶ サンプル:diff オプションの使用
BASH
# Show only the names of modified files
git diff --name-only
# Output:
# README.md
# file1.js
# file2.js
# Display File Modification Status
git diff --name-status
# Output:
# M README.md <- Edit
# A file1.js <- New
# D file2.js <- Delete
# R old.js new.js <- Rename
# Ignore differences in whitespace characters
git diff -w
# Ignore all spaces
git diff -w --ignore-blank-lines
# Show differences at the word level
git diff --word-diff
# Highlight in color
git diff --color-words
(2) コンテキスト制御
▶ サンプル:コンテキスト内の行数の制御
BASH
# Reduce the number of context lines
git diff -U1
# The output displays only1Line Context:
# @@ -10,3 +10,4 @@ function login() {
# const user = authenticate();
# + if (!user) return;
# return user;
# Do not display context
git diff -U0
# Increase the number of context lines
git diff -U10
(3) パスに関する制限
▶ サンプル:比較範囲の制限
BASH
# Compare only specific files
git diff -- file.js
# Compare only specific directories
git diff -- src/
# Exclude certain files
git diff -- . ':!*.test.js'
# Compare only a specific type of file
git diff -- '*.js'
6. 実社会での応用
(1) 提出前の確認
▶ サンプル:送信する前にしっかりと確認する
BASH
# 1. View Uncommitted Changes
git diff
# 2. View Staged Changes
git diff --staged
# 3. View Statistics on All Changes
git diff HEAD --stat
# 4. Submit after verifying that everything is correct
git commit -m "feat: Add a New Feature"
(2) コードレビュー
▶ サンプル:他人のコードのレビュー
BASH
# View the changes in a specific commit
git show a1b2c3d
# View statistics for a specific commit
git show --stat a1b2c3d
# View the list of files modified in a specific commit
git show --name-only a1b2c3d
# Compare the differences between the two branches
git diff main...feature
# ViewPull Requestthe differences
git diff origin/main...origin/feature
(3) 紛争分析
▶ サンプル:マージの競合の分析
BASH
# View the content to be merged
git diff main...feature
# View common ancestors up tofeatureChanges to
git diff $(git merge-base main feature) feature
# View files that may be in conflict
git diff --name-only main...feature
# View the specific details of the conflict
git diff main feature -- file.js
(4) バージョンのロールバックの確認
▶ サンプル:ロールバック内容の確認
BASH
# View content that would be lost if you undo the action
git diff HEAD HEAD~1
# View rollback statistics
git diff HEAD HEAD~1 --stat
# View the revision history for a specific file
git diff HEAD HEAD~1 -- file.js
# Execute the rollback after confirmation
git reset --hard HEAD~1
❓ よくある質問
Q git diff、git diff --staged、git diff HEAD の違いは何ですか?
A
git diff 作業ディレクトリとステージング領域(ステージングされていない変更)を比較する;git diff --staged ステージング領域とリポジトリ(ステージングされた変更)を比較する;git diff HEAD 作業ディレクトリとリポジトリ(コミットされていないすべての変更)を比較する。Q 変更されたファイルの内容そのものは表示せずに、ファイル名だけを表示するにはどうすればよいですか?
A
git diff --name-only を使用するとファイル名のみが表示され、git diff --stat を使用するとファイル名と変更統計情報が表示されます。Q diff 出力にある「+」と「-」の記号は何を意味するのですか?
A 「+」で始まる行は新規のコンテンツ、「-」で始まる行は削除されたコンテンツ、スペースで始まる行は元のテキスト(変更なし)を示しています。
Q 2つのブランチの違いを比較するにはどうすればよいですか?
A
git diff main feature を使用して 2 つのブランチを比較し、git diff main...feature を使用して、メインブランチに対する機能ブランチの変更点(フォークポイントから)を確認します。Q スペースの差異を無視するにはどうすればよいですか?
A
git diff -w を使用すると、スペースとタブの区別を無視し、git diff --ignore-space-at-eol を使用すると、末尾のスペースの有無による区別を無視します。📖 まとめ
- Git には、作業ディレクトリ、ステージング領域、リポジトリの 3 つの領域があります。
diffコマンドを使用すると、これら 3 つの領域のうち任意の 2 つを比較することができます。 - 作業ディレクトリとステージング領域の違い:
git diffステージングされていない変更を表示する - ステージング領域とリポジトリ:
git diff --stagedステージングされた変更を表示 - 作業ディレクトリとリポジトリの違い:
git diff HEADコミットされていない変更をすべて表示 - バージョンの比較:コミット、ブランチ、タグ間の相違点を比較する
- 豊富なdiffオプション:統計情報を表示する--stat、ファイル一覧を表示する--name-only、空白文字を無視する-w
📝 練習問題
-
基本演習:Gitリポジトリを作成します。ファイルを編集した後、
git diffを使用してステージングされていない変更を確認します。変更をステージングした後、git diff --stagedを使用してステージングされた変更を確認します。 -
応用演習:2つのブランチを作成し、異なるブランチ上で同じファイルに変更を加え、
git diffを使用して2つのブランチ間の相違点を比較し、発生しうる競合を分析してください。 -
課題:
git diffのさまざまなオプション(--stat、--name-status、-w など)を使用して、実際のプロジェクトに加えられた変更を分析し、完全な変更レポートを生成してください。