git diffってなんの差分出してるんだっけ? ~three treeの理解も添えて~
最近vimを使ってファイル編集することが多くなってきているのだが、git操作もvimで行いたいと思い、VSCodeでみていたGUI操作からCLI操作に慣れようと思った。ファイル編集してからの差分はgit diffでみていたのだが、このdiffはどことどこの差分なんだっけ?とふと思った。gitを全然理解していないことに気づいた4年目の夏
なので、この機会に改めて理解してみようと思う。
その前にindex, working tree, HEADも理解しておく
git diff理解の前にgitの典型的な開発ワークフローで出てくる3つの概念を押さえておく。(docsではthree treeと紹介されてる)
- working tree
- index
- HEAD
の3つ。 https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified
HEAD 直前のコミットの状態のこと。
index 次にコミットするファイル群のこと。 git addでindex(staging area)に追加できる。
working tree 編集しているファイルのこと。 indexにはいるファイルの前の状態。
git diffたち
素
オプションなしver
公式ではこうある
This form is to view the changes you made relative to the index (staging area for the next commit). In other words, the differences are what you could tell Git to further add to the index but you still haven’t.
このフォームは、インデックス (次のコミットのためのステージング領域) に対してあなたが行った変更を表示するものです。言い換えると、この差分は Git にさらにインデックスに追加するように指示することができるにもかかわらず、まだ追加していないものです。
indexに対する変更が表示される、なので、indexとworking treeの差分が出ているっぽい。
—cached(—staged)
git diff --cached
はindexとHEADの差分を見る。
一旦commit指定は考えないことにする。
状態遷移
実際のケースをもとにthree treeの状態を追っていく
前提
- ファイルAを編集する
- ファイルAはすでにコミットされている(直前のコミットハッシュをcommit-1とする)
ファイルAを編集(git add前)
diffの結果
-
git diff → Working vs Index
- → A’ と commit-1 の差分が見える(= 未ステージの変更)
-
git diff —cached → Index vs HEAD
- → どちらも commit-1 のため 差分なし
git add(ファイルAをindexに)
diffの結果
-
git diff → Working vs Index
- → どちらも A’ なので 差分なし
-
git diff —cached → Index vs HEAD
- → A’ と commit-1 の差分が見える(= 次のコミットに入る変更)
ファイルAをコミット
diffの結果
-
git diff → Working vs Index
- → 差分なし
-
git diff —cached → Index vs HEAD
- → 差分なし
まとめ表
状態 | HEAD | Index | Working | git diff (Working↔Index) | git diff --cached (Index↔HEAD) |
---|---|---|---|---|---|
編集直後 | commit-1 | commit-1 | A’ | A’ vs commit-1(見える) | なし |
git add A 後 | commit-1 | A’ | A’ | なし | A’ vs commit-1(見える) |
git commit 後 | commit-2 | commit-2 | commit-2 | なし | なし |