Git と Visual Studio 2017 その 12 : Git によるアイテムの比較
前回の記事では構成について触れました。今回は Git におけるアイテムの比較について見ていきます。Visual Studio については次回。
アイテムの比較 : Git
Git では diff コマンドを使ってアイテムの差分を確認できます。比較対象は、例えば 2 つのコミット間やステージングエリアのアイテムと作業ディレクトリのアイテム、またはブランチ間の差異などです。また、1 つのファイルを比較することも、ディレクトリごと比較することもできます。早速やってみましょう。
2 つのコミットを比較
1. まず ‘git log --oneline --graph --all’ を実行して現状の確認。第 10 回の記事の最後で、リモートより dev ブランチをチェックアウトし忘れた模様。
2. ‘git diff HEAD~1 HEAD' を実行。HEAD は現在のブランチがポイントするコミット e45a3c6 を示し、HEAD~1 は直前の c69d3e9 コミットを示すため、これらの差分が表示。ただし文字化けしている。README.md はもともと GitHub で作成されたため README.md は UTF-8 で作成されているが、コミット 5c96d7c を行った際、’echo “文字列” >> README.md’ で文字列を追加したため、その部分だけ SJIS になったため。(反省)。読み方は以下の通り。
- 1 行目: どのファイルを比較しているか及び、HEAD~1 を a、HEADを b とするという表示
- 2 行目: それぞれの Git ブロブオブジェクト ID
- 3,4 行目: a のことを ”-” という記号で示し、b のことを ”+” で示すよという表示
- 5 行目: - (つまり a) の 1 行目から 2行、および + (つまり b) の 1 行目から 3 行表示するよという意味
- 6 行目以降: ファイルの中身。+ も - もない行は a/b 同じという意味。
3. ‘git cat-file blob 64d5594’ と ‘git cat-file blob b104f70’ でそれぞれの README.md を表示。やはり前者は化けている。
4. HEAD~1 は HEAD の直前のコミットを指しているが、実際コミットe45a3c6 はマージコミットであるため、親コミットを 2 つ持っている。‘git cat-file commit HEAD’ を実行して中身を確認すると parent が 2 つあるが、上にあるものと HEAD~1 が同じであることを確認。
5. ‘git rev-parse HEAD~1’ を実行するとラベルから実際の SHA1 ハッシュ値を確認可能。
6. ‘git log --oneline --first-parent’ ではじめの親だけをツリー表示可能。
7. 他方の親コミットを比較したい場合は、’git diff c69d3e9 HEAD’ のようにコミット ID を指定。先ほどより多くの差分が表示される。
8. 情報が出すぎる場合は ‘git diff --raw c69d3e9 HEAD’ や ‘git diff --stat c69d3e9 HEAD’ を利用可能。
特定のアイテムを比較
特定のファイルやディレクトリだけを比較することも可能です。
1. ‘git diff c69d3e9 HEAD README.md’ を実行。先ほどと異なり、README.md のみ差分表示。
2. ‘git diff --stat HEAD~5 HEAD VS_Git’ を実行すれば、過去 5 コミットに関して VS_Git ディレクトリのみ差分のまとめが表示。
作業ディレクトリ、ステージングエリア、コミット間の差分
コミットされたものではなく、現在作業中のアイテムを比較する場合も見ていきます。
1. コマンドプロンプトよりファイルを編集するが、前回の過ちを繰り返さないためにまず文字コード変更。’chcp 65001’ を実行。その後 ‘echo “ステージに追加” >> README.md’ および ‘git add README.md’ を実行。
2. 次に ‘echo “作業ディレクトリで編集中” >> README.md’ 実行後、‘git status’ で現状確認。ステージングエリアと作業ディレクトリに README.md の表示を確認。
3. ‘git diff’ を実行。この場合ステージングエリアと作業ディレクトリのアイテムを比較。
4. ‘git diff --cached’ を実行。この場合 HEAD とステージングエリアのアイテムを比較。
5. ‘git diff HEAD’ を実行。この場合 HEAD と作業ディレクトリのアイテムを比較。
6. ファイルも確認。’git cat-file blob b104f70’ を実行すると HEAD にある README.md が表示。
7. ‘git cat-file blob 3fc4263’ 実行ではエラーが表示。これは作業ディレクトリのアイテムは Git オブジェクト化されていないため。
8. Git は add コマンド実行時にアイテムを Git オブジェクトとして作成するが、作業ディレクトリのアイテムが SHA1 ハッシュ値を持っている理由は、Git がリアルタイムにハッシュ値を計算したため。‘git hash-object README.md’ を実行すると同じハッシュ値が得られる。
ブランチ間の比較
最後にブランチ間の比較を試します。
1. ‘git checkout -b dev’ を実行してブランチ作成と同時にチェックアウト。ステージングエリアと作業ディレクトリのアイテムはそのまま。
2. ‘git commit -m “ステージに追加された README.md をコミット”’ を実行。
3. ‘git diff dev master’ を実行して、ブランチ間の差異を確認。
4. ‘git diff dev…master' を実行。この場合は先ほどと異なり、dev ブランチ作成後に master ブランチで変更された内容だけが表示される。よって現時点は何もなし。
5. ‘git checkout -f master’ でブランチを変更後、‘echo “マスターで追加” >> README.md’ および ‘git commit -am “README.md をマスターで編集”’ を実行してコミット作成。
6. 再度 ‘git diff dev master’ と ‘git diff dev…master’ を実行して内容を確認。
リセット
次の記事のために、以下コマンドで状況をリセット。
‘git checkout master’
‘git branch -D dev’
‘git reset --hard e45a3c6’
まとめ
アイテムの比較は問題が発生した場合などにとても重要です。Visual Studio での比較に慣れているため Git の機能はあまり知りませんでしたが、とても便利に使えることが分かりました。次回は Visual Studio でのアイテム比較機能を見ていきます。次の記事へ
中村 憲一郎