git diffとは何か?
Gitの中でもよく使うコマンドの一つに「git diff」があります。
diffはdifferenceの略で、その名の通り指定したコミットやファイルの違い(差分)を表示するコマンドです。
「git diff」単体で使われることもありますが、「–cached」などのオプションをつけたり引数を指定して使うことも頻繁にあります。
思っている以上に柔軟でできることが多いので、オプションや引数に何を指定するかで、比較する対象が変わるので注意が必要です。
例えば、単に「git diff」を実行したときでも、自分が何を比較したときの差分を見ているかを理解できていることが重要です。
ここでは、「git diff」の使い方やgit diffで表示される内容の見方についてまとめています。
git diffの内容|ステージ(インデックス) vs 作業ツリー
引数を指定しないgit diff
を実行したときに表示されるのは、ステージ(インデックス)と作業ツリーの内容の差分です。
Gitは主に以下の4つの階層に分けて考えることができます。
リモートレポジトリ(Github)
↑ push
ローカルレポジトリ
↑ commit
ステージ(インデックス)
↑ add
作業ツリー(ワークツリー)←ココ
すなわちgit diffがやっているのは、git addする前のファイルと、最新のコミットとの差分を表示しているということです。
このため、対象のファイルをgit addした後にgit diffを実行すると、そのファイルの差分は表示されなくなります。
git diffの実例と表示内容の見方
git add前の変更したファイルが存在するときに、実際にgit diffを実行した場合の例は以下のようになります。
$ git diff
diff --git a/index.html b/index.html
index 60f3b81..71b41cf 100644
--- a/index.html
+++ b/index.html
@@ -7,5 +7,6 @@
</head>
<body>
<h1>add h1</h1>
+ <h2>add h2</h2>
</body>
</html>
変更内容はindex.htmlファイルにh2タグを追加した処理です。
以下で表示されている内容について解説します。
1行目|diff –git a/index.html b/index.html
1行目はdiff --git a/index.html b/index.html
です。
「–git」は冒頭の「diff」がgitコマンドであることを示しています。
すなわち、比較元ファイル「a/index.html」と、比較対象ファイル「b/index.html」をgit diffに渡したということを示しています。
比較元と比較対象のファイルに「a/」と「b/」を自動でつけて判別できるようにしています。
2行目|index 60f3b81..71b41cf 100644
2行目はindex 60f3b81..71b41cf 100644
です。
ここの内容は「 2行目|60f3b81..71b41cf」と「100644」の2つに分かれます。
index 60f3b81..71b41cfとは何か?
「60f3b81」と「71b41cd」は各ファイルの状態を示すGitのハッシュ値を示しています。
<比較元のファイルのハッシュ値>..<比較対象のファイルのハッシュ値>
実際に、コミットの詳細を確認するgit showを使って対象のハッシュ値を調べる(git show 60f3b81
)とファイルの中身が表示されます。
$ git show 60f3b81
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>add h1</h1>
</body>
</html>
100644とは何か?
ファイルのハッシュ値の後ろに表示される「100644」はファイルのアクセス権限を示してます。
100644の「644は rw-r–r–」の意味です。
100644の他に、100755という表記もよく見かけます。「755はrwxr-xr-x」の意味です。
3行目| --- a/index.html
3行目は--- a/index.html
です。
下部に表示される変更内容で、比較元(変更前)のファイルで変化があった箇所を「-」で表すという意味です。
4行目|+++ b/index.html
4行目は+++ b/index.html
です。
下部に表示される変更内容で、比較先(変更後)のファイルで変化があった箇所を「+」で表すという意味です。
5行目| @@ -7,5 +7,6 @@
5行目は@@ -7,5 +7,6 @@
です。
この下に表示しているコードが、比較元と比較先のファイルのどの行に当たるかを示しています。
「-」:比較元のファイル(— a/index.html = 60f3b81)
「+」:比較対象のファイル(+++ b/index.html = 71b41cf)
7.5や7.6の意味
7.5や7.6は、ファイルの中のx行目から、y桁分を表示するという意味です。
「x,y」:ファイルのx行目から、y行分を表示なので、「7,5」なら、7行目から5行分 (7~11行)を表示という意味です。
実例
git diffの表示内容
$ git diff
diff --git a/index.html b/index.html
index 60f3b81..71b41cf 100644
--- a/index.html
+++ b/index.html
@@ -7,5 +7,6 @@
</head>
<body>
<h1>add h1</h1>
+ <h2>add h2</h2>
</body>
</html>
(参考)元ファイル(a/index.html)
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Document</title>
7 </head>
8 <body>
9 <h1>add h1</h1>
10 </body>
11 </html>
6行目|実際のコード
6行目には実際に変更があった場所に該当するコードが表示されます。
</head>
<body>
<h1>add h1</h1>
+ <h2>add h2</h2>
</body>
</html>
ファイルの変更点は以下のように表示されます。
つまり、上記のコードの表示は、現在作業中のワークツリーを、最新のコミットと比較すると、index.htmlファイルにh2タグが新たに追加されているという内容を示しています。
git add後のgit diff
参考として、上記のgit diffで表示されていた、index.htmlファイルをgit addした場合にどうなるかも示しておきます。
git addでワークツリーの内容をステージ(インデックス)に上げると、ワークツリーとステージの差分はなくなるため、git diffで何も表示されなくなります。
$ git add index.html
$ git diff
$
git addした後のコミットと最新のステージを比較する方法については後述します。
コミット番号を指定して比較する(指定コミット vs 作業ツリー)
git diffの引数にコミットを指定すると、指定したコミットと作業ツリーの差分を表示することができます。
git diff コミット番号
引数を何も指定しない場合は最新のコミットとの比較だったため、git addするとgit diffで何も表示されなくなりましたが、コミット番号を指定した場合は差分が表示されます。
実例
git diffでコミット番号を指定すると、以下のように指定したコミットと現時点での作業ツリーとの差分が表示されます。
$ git diff 9cbd2d7
diff --git a/Gemfile b/Gemfile
index 95d4db3..26db9b9 100644
--- a/Gemfile
+++ b/Gemfile
@@ -23,7 +23,7 @@ gem 'jbuilder', '~> 2.7'
# gem 'bcrypt', '~> 3.1.7'
# Use Active Storage variant
-# gem 'image_processing', '~> 1.2'
+gem 'image_processing', '~> 1.2'
コミット番号以外の指定方法
差分を表示するコミットを指定するときに、コミット番号以外にも「HEAD(または@)」や「tag名」を使って指定することもできます。
実例
例えば次のようなコミットがあるとします。
$ git log --oneline
0193c66 (HEAD -> master, tag: v1.0) add h1
この場合、「0193c66」=「HEAD」=「v1.0」となります。
コミット番号で指定した場合
$ git diff 0193c66
diff --git a/index.html b/index.html
index 60f3b81..71b41cf 100644
--- a/index.html
+++ b/index.html
@@ -7,5 +7,6 @@
</head>
<body>
<h1>add h1</h1>
+ <h2>add h2</h2>
</body>
</html>
HEADで指定した場合
$ git diff HEAD
diff --git a/index.html b/index.html
index 60f3b81..71b41cf 100644
--- a/index.html
+++ b/index.html
@@ -7,5 +7,6 @@
</head>
<body>
<h1>add h1</h1>
+ <h2>add h2</h2>
</body>
</html>
v1.0で指定した場合
$ git diff v1.0
diff --git a/index.html b/index.html
index 60f3b81..71b41cf 100644
--- a/index.html
+++ b/index.html
@@ -7,5 +7,6 @@
</head>
<body>
<h1>add h1</h1>
+ <h2>add h2</h2>
</body>
</html>
過去のコミットを簡単に指定する方法
現在からみて、1つ前や2つ前など過去のコミットを指定するとても簡単な方法があります。
それは「HEAD^」(または@^)です。遡りたいコミットの数だけ「^」をつけます。
$ git diff HEAD^^
diff --git a/index.html b/index.html
index e69de29..71b41cf 100644
--- a/index.html
+++ b/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Document</title>
+</head>
+<body>
+ <h1>add h1</h1>
+ <h2>add h2</h2>
+</body>
+</html>
git add後の差分を見る方法|指定コミット vs ステージ(インデックス)
git diffではgit addすると差分が見えなくなってしまいます。ですが、git addした後で、コミット前に差分を確認したいことが(頻繁に)発生することがあります。
その場合、方法は非常に簡単で、--cached
をつけるだけです。これで、ステージの状態と最新のコミットを比較することができます。
git diff --cached
リモートレポジトリ(Github)
↑ push
ローカルレポジトリ
↑ commit
ステージ(インデックス)←ココ
↑ add
作業ツリー(ワークツリー)
なお、–chacnedオプションのみで引数がない場合は、現在の最新のコミット内容とステージの状態を比較します。
実例
$ git diff --cached
diff --git a/index.html b/index.html
index 60f3b81..71b41cf 100644
--- a/index.html
+++ b/index.html
@@ -7,5 +7,6 @@
</head>
<body>
<h1>add h1</h1>
+ <h2>add h2</h2>
</body>
</html>
ステージと指定したコミットの差分を確認する方法
引数でコミット番号を指定することで、指定したコミットの内容とステージングの状態を比較することもできます。
git diff --cached <コミット番号>
▼実例
$ git diff --cached HEAD^^
diff --git a/index.html b/index.html
index e69de29..71b41cf 100644
--- a/index.html
+++ b/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Document</title>
+</head>
+<body>
+ <h1>add h1</h1>
+ <h2>add h2</h2>
+</body>
+</html>
比較元コミット vs 比較先コミット
コミットを指定することで、コミット同士の比較も可能。
git diff <比較元コミット> <比較先コミット>
基本的に比較元は古いコミットを指定する。(出力結果で追加された項目が+で表示されるため)
例えば、現在のコミットと3つまえのコミットを比較する場合は「$ git diff HEAD^^^ HEAD」
$ git diff HEAD^^^ HEAD
diff --git a/index.html b/index.html
index 71b41cf..7e03fa2 100644
--- a/index.html
+++ b/index.html
@@ -8,5 +8,8 @@
<body>
<h1>add h1</h1>
<h2>add h2</h2>
+
+ <h3>add h3</h3>
+ <h4>add h4</h4>
</body>
</html>
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..e69de29
▼引数を逆にした場合
引数を逆にすれば、+と−の符号が置き換わる。
$ git diff HEAD HEAD^^^
diff --git a/index.html b/index.html
index 7e03fa2..71b41cf 100644
--- a/index.html
+++ b/index.html
@@ -8,8 +8,5 @@
<body>
<h1>add h1</h1>
<h2>add h2</h2>
-
- <h3>add h3</h3>
- <h4>add h4</h4>
</body>
</html>
diff --git a/style.css b/style.css
deleted file mode 100644
index e69de29..0000000
指定ブランチ vs 作業ツリー
git diff <コミット>
で指定コミットと作業ツリーを比較できたが、ブランチを指定すれば、指定ブランチと作業ツリーを比較できる。
git diff <ブランチ名>
$ git diff ft1
diff --git a/index.html b/index.html
index 7636e4b..7e03fa2 100644
--- a/index.html
+++ b/index.html
@@ -10,5 +10,6 @@
<h2>add h2</h2>
<h3>add h3</h3>
+ <h4>add h4</h4>
</body>
</html>
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..e69de29
指定ブランチ vs 指定ブランチ(リモートブランチも可)
ブランチ同士の差分を比較することも可能。
git diff <比較元ブランチ名> <比較先ブランチ名>
ローカルブランチ同士の比較
$ git diff ft1 master
diff --git a/index.html b/index.html
index 7636e4b..7e03fa2 100644
--- a/index.html
+++ b/index.html
@@ -10,5 +10,6 @@
<h2>add h2</h2>
<h3>add h3</h3>
+ <h4>add h4</h4>
</body>
</html>
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..e69de29
変更点は2つあることがわかる。
(1)masterはindex.htmlにはh4タグがない(ft1にはh4タグが追加されている)。
(2)masterにはstyle.cssファイルが新規作成されている(ft1にはない)
ソースコードの+, -とファイル追加のnew, deleteが微妙にわかりにくい。。
ローカルブランチとリモートブランチの比較
git diff <ローカルブランチ名> <リモートレポジトリ名/ブランチ名>
▼実例
ローカルのmasterブランチと、リモートレポジトリ名originのmasterブランチを比較。
$ git diff master origin/master
diff --git a/index.html b/index.html
index 9d8e2e9..7e03fa2 100644
--- a/index.html
+++ b/index.html
@@ -11,7 +11,5 @@
<h3>add h3</h3>
<h4>add h4</h4>
-
- <h5>add h5</h5>
</body>
</html>
指定ブランチ vs 指定ブランチの共通先祖
git diff <比較元ブランチ名> <共通先祖を参照するブランチ名>
▼実例
git diff ft1...master
この場合、ft1と、ft1とmasterの共通先祖のコミットを比較する。
$ git diff ft1...master
diff --git a/index.html b/index.html
index 7636e4b..9d8e2e9 100644
--- a/index.html
+++ b/index.html
@@ -10,5 +10,8 @@
<h2>add h2</h2>
<h3>add h3</h3>
+ <h4>add h4</h4>
+
+ <h5>add h5</h5>
</body>
</html>
diff --git a/style.css b/style.css
new file mode 100644
▼(参考)ドットなしの場合
ドットがない場合は、指定したブランチ同士の比較となる。
$ git diff ft1 master
diff --git a/index.html b/index.html
index 7636e4b..9d8e2e9 100644
--- a/index.html
+++ b/index.html
@@ -10,5 +10,8 @@
<h2>add h2</h2>
<h3>add h3</h3>
+ <h4>add h4</h4>
+
+ <h5>add h5</h5>
</body>
</html>
diff --git a/main.js b/style.css
similarity index 100%
rename from main.js
rename to style.css
「diff A B」と「diff A..B」は同じ
コマンドの記述で、間にドット2つ(..)がある場合があるが、これはドットの前後を比較している意味。
ドットなしと同じ結果となる。
▼実例
$ git diff HEAD HEAD^
diff --git a/index.html b/index.html
index 9d8e2e9..7e03fa2 100644
--- a/index.html
+++ b/index.html
@@ -11,7 +11,5 @@
<h3>add h3</h3>
<h4>add h4</h4>
-
- <h5>add h5</h5>
</body>
</html>
$ git diff HEAD..HEAD^
diff --git a/index.html b/index.html
index 9d8e2e9..7e03fa2 100644
--- a/index.html
+++ b/index.html
@@ -11,7 +11,5 @@
<h3>add h3</h3>
<h4>add h4</h4>
-
- <h5>add h5</h5>
</body>
</html>
「..」と「…」の違い
git diff A..B
とgit diff A...B
はドット2つとドット3つの差ですが、実行内容は大きく異なります。
ドット2つ git diff A..B
ブランチAとブランチBを比較。
ドット3つ git diff A...B
ブランチAと、ブランチAとブランチBの共通祖先を比較。
git diffの便利なオプション
変更のあるファイル名のみ表示(–name-only)
--name-only
をつけると、変更のあるファイル名のみを表示する。表示がだいぶ短くなる。
$ git diff ft1 master --name-only
index.html
style.css
ft1ブランチとmasterブランチを比較すると、index.htmlとstyle.cssの2つのファイルに違いがあることが一目でわかる。
▼(参考)比較用
$ git diff ft1 master
diff --git a/index.html b/index.html
index 7636e4b..9d8e2e9 100644
--- a/index.html
+++ b/index.html
@@ -10,5 +10,8 @@
<h2>add h2</h2>
<h3>add h3</h3>
+ <h4>add h4</h4>
+
+ <h5>add h5</h5>
</body>
</html>
diff --git a/main.js b/style.css
similarity index 100%
rename from main.js
rename to style.css
2つ以上の連続するスペースを無視(-b)
-b
オプションをつけると2つ以上の連続するスペースの差分は無視した、差分を表示する。
--ignore-space-changes
と同じ。
▼参考
$ git diff -b
diff --git a/index.html b/index.html
index 9d8e2e9..c3e3029 100644
--- a/index.html
+++ b/index.html
@@ -9,9 +9,11 @@
<h1>add h1</h1>
<h2>add h2</h2>
- <h3>add h3</h3>
+
+
+ <h3>a d d h3</h3>
<h4>add h4</h4>
- <h5>add h5</h5>
+ <h5>a d d h5</h5>
</body>
</html>
$ git diff
diff --git a/index.html b/index.html
index 9d8e2e9..c3e3029 100644
--- a/index.html
+++ b/index.html
@@ -9,9 +9,11 @@
<h1>add h1</h1>
<h2>add h2</h2>
- <h3>add h3</h3>
- <h4>add h4</h4>
- <h5>add h5</h5>
+
+ <h3>a d d h3</h3>
+ <h4>add h4</h4>
+
+ <h5>a d d h5</h5>
</body>
</html>
スペースを無視(-w)
-w
オプションをつけるとスペースの差分は無視した、差分を表示する。
--ignore-all-changes
と同じ。
▼参考
$ git diff -w
diff --git a/index.html b/index.html
index 9d8e2e9..c3e3029 100644
--- a/index.html
+++ b/index.html
@@ -9,6 +9,8 @@
<h1>add h1</h1>
<h2>add h2</h2>
+
+
<h3>a d d h3</h3>
<h4>add h4</h4>
$ git diff
diff --git a/index.html b/index.html
index 9d8e2e9..c3e3029 100644
--- a/index.html
+++ b/index.html
@@ -9,9 +9,11 @@
<h1>add h1</h1>
<h2>add h2</h2>
- <h3>add h3</h3>
- <h4>add h4</h4>
- <h5>add h5</h5>
+
+ <h3>a d d h3</h3>
+ <h4>add h4</h4>
+
+ <h5>a d d h5</h5>
</body>
</html>