htsign's blog

ノンジャンルで書くつもりだけど技術系が多いんじゃないかと思います

git stash の tips

git stash、使ってますか?
作業中の内容を一旦別に追いやることで他のコマンドを阻害しなくなる便利なコマンドです。
git stashの詳細については、Qiitaやら各種ブログやらで説明していらっしゃる先人がたくさんおりますので、そちらにお譲りします。

tl;dr

git stash <subcommand> stash@{<n>} を省略して git stash <subcommand> <n> と書ける。

本文

みなさんご存じの通り、Gitの各種コマンドには様々なサブコマンドがあり、この git stash も例外ではありません。
この内、

  • git stash show
  • git stash apply
  • git stash pop
  • git stash drop
  • git stash branch

は何も引数を与えず実行すると、暗黙的に stash@{0} が採用されたものと見做されます1

で、引数を与える場合、特にstashの番号を与える場合は stash@{2} とか stash@{3} とか、 stash@{n} のフォーマットで書きます。
これ、数タイプではありますが結構面倒くさいですよね。typoの可能性だって出て来ます。

GitはコミットをSHA1のハッシュで管理しています。
多くのGitコマンドはコミットの指定にハッシュ値の入力を要求しますが2、このハッシュ値は現在のリポジトリの中で一意に特定さえできれば、最低4文字まで省略できることになっています。

例えば、リポジトリcaf1234... というコミットがあり、 他に caf1 で始まる他のコミットがなければ、
git checkout caf1 でこのコミットにチェックアウトすることができます。
caf10... というコミットが他にあれば caf1 では候補が2つあることになってしまうので、
一文字追加して git checkout caf12 でチェックアウトできますね3

で、私思いました。ハッシュ値が省略できるなら、もしかしたらstashの指定も省略できるのではないかと。
何気なく git stash drop 1 と入力して実行してみたら、何と、通りました。

ドキュメントを読んでみるとこんな記述があります。

The latest stash you created is stored in refs/stash; older stashes are found in the reflog of this reference and can be named using the usual reflog syntax (e.g. stash@{0} is the most recently created stash, stash@{1} is the one before it, stash@{2.hours.ago} is also possible). Stashes may also be referenced by specifying just the stash index (e.g. the integer n is equivalent to stash@{n}).

太字部分を雑に訳すと「インデックスだけを指定して参照することもできます(例えば nstash@{n} と等価です)」といった感じでしょうか。

恥ずかしながら、今までこの略記を知りませんでした。
いろいろな git stash に言及している記事を読んでもこの略記について触れているものは私の観測範囲にはありませんでした。
意外と知られていないのかな、と思ってこのエントリを書きました。

ちなみに HEAD@ という略記がありますが、これは結構有名ですよね。

ref: Git - git-stash Documentation


  1. ドキュメントを読むと必ずしも stash@{0} ではないかのようなニュアンスで書かれていますが…

  2. またはシンボル(master とか)やタグなど

  3. 一意に定まらない場合はあいまいな候補のリストを表示してくれます。