🦁

間違って消してしまった git stash を元に戻す(PowerShell)

2021/03/28に公開

前置き

ある時Gitに残ったStashを整理しようとVSCodeのGitLensを使って消していたのですが、うっかり作業中のStashまで消してしまいました。焦ってGoogle先生に助けを求めたところ、以下の記事に助けられました。

git stashをコミットもなしに消してしまった時の対応 - Qiita

コマンドがMac向けでしたので、Windowsユーザの自分用にPowerShell向けに書き直してみました。

環境

  • Windows 10
  • PowerShell 6.2.2
  • git version 2.17.1.windows.2

本題

まず、Git内にある宙ぶらりんのオブジェクトを確認します。
Git - システム管理

powershell
> git fsck --lost-found
Checking object directories: 100% (256/256), done.
Checking objects: 100% (189/189), done.
dangling commit 5bb836c4a1ecfbcca27d87f66a53007380962efb
dangling commit 7c75d438ab033ddafe60833325b216e8b7355636
dangling commit 137af08c3282051d0ea00c62da76af6d5fb9ae3c

ここではcommitだけですが、blobなども出てきたりするのでフィルタをかけます。

powershell
> git fsck --lost-found | ?{ $_ -match "commit" }

?Where-Objectのエイリアスです。(下で出てくる%ForEach-Objectです)
結果は上と同じですね。(サンプルが悪くて申し訳ないです)
こうして残ったコミットから残したいコミットを探し出すのですが、一々git showするのも手間なのでコミットIDを使って一覧にしてしまいます。

powershell
> git fsck --lost-found | ?{ $_ -match "commit"} | %{ ($_ -split ' ')[2] } | %{ git show --no-patch $_ }
Checking object directories: 100% (256/256), done.
Checking objects: 100% (189/189), done.
commit 5bb836c4a1ecfbcca27d87f66a53007380962efb
Merge: 96ff14c ecb531e
Author: *********
Date:   Thu Oct 26 20:52:35 2017 +0900

    comment
commit 7c75d438ab033ddafe60833325b216e8b7355636
Author: *********
Date:   Thu Jan 16 01:35:01 2020 +0900

    test
commit 137af08c3282051d0ea00c62da76af6d5fb9ae3c
Author: *********
Date:   Thu Jan 16 01:35:36 2020 +0900

    test

こうして一覧にされた宙ぶらりんのコミット群の中から該当するコミットをチェリーピックします。

powershell
git cherry-pick -n -m1 <commit id>

これでローカルに復活させることができました。めでたしめでたし。

サンプルに適当なローカルリポジトリでやりましたが、意外と2017年のコミットとか残っていたりするんですね。多少びっくりしました。

参考URL

Discussion