1. 概要

gitstashgitstash pop などのコマンドは、作業ディレクトリの変更をシェルブ(スタッシュ)および復元するために使用されます。 このチュートリアルでは、Gitでドロップされたスタッシュを回復する方法を学習します。

2. 作業ディレクトリの変更を隠します

この例では、Gitリポジトリをフォークしてクローンを作成したとします。 次に、 README.md ファイルの最後に新しい行を追加し、作業ディレクトリのステータスを確認するだけで、いくつかの変更を加えましょう。

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

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:   README.md

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

ここから、 git stash コマンドを使用して、変更を一時的に保留できます。

$ git stash
Saved working directory and index state WIP on master: a8088442db Updated pom.xml

ここで、 git status をもう一度実行すると、作業ディレクトリがクリーンであることがわかります。

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

nothing to commit, working tree clean

3. 隠された変更の復元とハッシュの検索

隠された変更を復元し、隠しコミットに関連付けられたハッシュを見つける方法を見てみましょう。

3.1. 隠された変更を作業ディレクトリに復元する

隠した変更を次のように作業ディレクトリに戻すことができます。

$ git stash pop
On branch master
Your branch is up to date with 'origin/master'.

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:   README.md

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (59861637f7b599d87cb7a1ff003f1b0212e8908e)

最後の行でわかるように、 git stash popは、隠された変更を復元するだけでなく、関連するコミットへの参照も削除します。

3.2. ターミナルが開いているときのハッシュの位置

端末がまだ開いている場合は、 git stashpopの実行後に生成されたハッシュを簡単に見つけることができます。 この例では、最後の行に表示されるハッシュは59861637f7b599d87cb7a1ff003f1b0212e8908eです。

3.3. ターミナル閉鎖後のハッシュの復旧

ターミナルを閉じた場合でも、次の方法でハッシュを見つけることができます。

$ git fsck --no-reflog
Checking object directories: 100% (256/256), done.
Checking objects: 100% (302901/302901), done.
dangling commit 59861637f7b599d87cb7a1ff003f1b0212e8908e

ドロップされたスタッシュのコミットハッシュが表示されるようになりました。

4. ドロップされたスタッシュの回復

一度適用すると、通常はスタッシュエントリは必要ありません。 ただし、ドロップした後、スタッシュエントリに戻りたい場合があります。 たとえば、 git reset –hard HEADを使用すると、コミットされていないすべての変更が作業ディレクトリから破棄されます。この状況では、以前に隠されていた変更が削除された場合でも、それらを取り消すことができます。

4.1. ハッシュを使用してスタッシュを復元する

ぶら下がっているコミットにハッシュを使用しても、これらの変更を回復することは可能です。

$ git stash apply 59861637f7b599d87cb7a1ff003f1b0212e8908e
On branch master
Your branch is up to date with 'origin/master'.

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:   README.md

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

以前に隠しておいた変更を使用して、作業ディレクトリが復元されていることがわかります。

4.2. すべてのハッシュコミットを見つける

すぐに利用できるハッシュがない場合は、次のように見つけることができます。

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

ここでは、 –no-reflogオプションとawk を組み合わせて、ハッシュのみを除外します。

5. 結論

この記事では、 git stash がどのように機能し、使用時にエントリがどのようにドロップされるかを確認しました。 次に、ハッシュがわかっているときにドロップされたエントリを引き続き使用する方法と、stashコミットのハッシュを見つける方法を確認しました。