DESIGN / CODE / INFRA / AI

解説

過去のファイルを、作業中の内容を変えずに読む:git showの使い方

古いコミットの中身を見たいとき、先にcheckoutせず表示だけで確認。コミットの選び方と、保存する場合の注意点を練習ファイルで試そう。

過去のファイルを、作業中の内容を変えずに読む:git showの使い方

「昨日のコミットでは、この設定に何と書いてあった?」と調べたいだけなら、作業中のファイルを過去へ戻す必要はない。git showで、過去のコミットが持つファイルの内容を表示できるよ。

この記事では、Gitに記録済みのテキストを読む操作に絞る。Gitが導入済みで、少なくとも一つコミットのあるリポジトリが前提。初めてなら、後半の練習用フォルダを使おう。

まずコミットを選ぶ

git log --oneline --max-count=5

各行の先頭にある短い英数字は、コミットを識別するID。メッセージと日付なども確認し、目的の変更の前後を選ぼう。メッセージだけで内容を断定せず、実際のファイルも読むのが次の手順だよ。

コミットとファイルのパスを指定する

git show HEAD:note.txt
git show HEAD~1:note.txt

HEADは現在のコミット、HEAD~1はその一つ前の第一親のコミットを指す。マージのある履歴では、単に「日時順の一つ前」と同じとは限らない。特定の状態を選ぶなら、確認したコミットIDをHEAD~1の代わりに使おう。

コロンの後ろは、コミット内のファイルのパス。ここでは混乱を避けるため、リポジトリの最上位からのパスを使う。ディレクトリ内のファイルなら、HEAD:config/example.txtのように指定する。

git show HEADだけなら、通常はコミット情報と変更内容を表示する。git show HEAD:note.txtは、その時点のファイルそのものの内容を表示する指定だよ。

練習では、保存済みと編集中を別にする

次はPOSIX系シェルの例。新しい一時フォルダだけを使う。

practice_dir=$(mktemp -d)
cd "$practice_dir"
git init -q
printf 'mode=old
' > note.txt
git add note.txt
git -c user.name=Practice -c user.email=practice@example.invalid commit -qm 'Old setting'
printf 'mode=new
' > note.txt
git add note.txt
git -c user.name=Practice -c user.email=practice@example.invalid commit -qm 'New setting'
printf 'mode=draft
' > note.txt

git show HEAD~1:note.txt
git show HEAD:note.txt
cat note.txt

期待する出力は順番にmode=old、mode=new、mode=draft。過去二つの状態を表示しても、作業中のファイルはdraftのまま残る。編集部では一時リポジトリで、この三つの出力とファイルが変わらないことを確認した。

エラーが出たときの見方

HEAD~1が存在しなければ、一つ前のコミットを選べない。コミットが一つしかない場合などは、git logで存在する履歴を確認する。

ファイルがそのコミットに存在しないときもエラーになる。追加前の履歴や、名前変更前のファイルを見ていないか、git ls-tree -r --name-only HEAD~1でその時点のパスを調べよう。

ファイルへ保存する場合は、出力先に注意

画面に表示するだけのコマンドと、>でファイルへ書くコマンドは影響が違う。たとえばgit show HEAD:note.txt > note.txtとすると、作業中のnote.txtを上書きする。表示確認のつもりで付け足さないでね。

別名へ保存したい場合も、出力先に必要なファイルがないことを確認する。秘密情報を含む過去のファイルは、ログや共有画面へ出さないようにしよう。いまの変更を比較するなら、diffの三つの比較対象を使い分けられるよ。

参考・出典

みんなのコメント 0

感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。

最初のコメントをどうぞ。