[小ネタ] Git履歴から単一ファイルを復元する

こんにちは。サービスグループの武田です。Gitを利用してソースコード管理をしている場合、過去の特定のコミット時点の状態にファイルを復元できます。
2022.03.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。サービスグループの武田です。

Gitを利用してソースコード管理をしている場合、過去のコミット履歴を参照することでどのような変更をしたのかなどが簡単に確認できます。またその履歴から、特定のコミット時点の状態にファイルを復元できます。

以前はgit checkoutで行いましたが、現在はgit restoreが推奨です。

基本的な構文はシンプルにファイルパスを指定するだけです。

$ git restore <file_path>

HEADから復元する

「ファイル途中まで編集したんだけど、やっぱやめた」というときに使います。編集量によってはCtrl-Zで戻すことも可能でしょうが、エディタ依存ですし、サクッと最後のコミット時点まで戻しましょう。

$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   package.json

no changes added to commit (use "git add" and/or "git commit -a")
$ git restore package.json
$ git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

少し前のコミットから復元する

「コミットしたんだけど、その前の状態に戻したい」というときに使います。git restoreには-s/--sourceオプションが用意されており、戻したいコミットを指定できます。

$ git restore -s @~2 package.json
$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   package.json

no changes added to commit (use "git add" and/or "git commit -a")

コミットハッシュを指定して復元する

上記の方法と同じですが、コミットハッシュを用いて特定地点を指定できます。

git logで履歴を確認し、戻したい地点のコミットハッシュを確認します。

$ git log --oneline
d498b99 (HEAD -> main, origin/main, origin/HEAD) npm audit fix
2bb8606 npx ncu -u && npm install
95ccbb0 辞書追加
1b197f6 whitelistにワード追加
678b448 npx ncu -u && npm install
37e8bbf 分報が引っかかるのでホワイトリストに追加
c58c752 npm audit fix
299b9e0 npx ncu -u && npm install

たとえば678b448の地点に戻したいのであれば、-sでそれを指定します。

$ git restore -s 678b448 package.json
$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   package.json

no changes added to commit (use "git add" and/or "git commit -a")

まとめ

いつも-s/--sourceオプションの存在を忘れてよくググります。頻繁に使うわけではないのですが、使いたいときには思い出してサクッと復元できるようにしておきましょう。