White scenery @showyou, hatena

If you have any comments, you may also send twitter @shsub or @showyou.

git stash

git stashは「今やってるやつのと別の修正をしなきゃいけない、だけど今のやつはコミットしたくない!」って時に使います。


シナリオ


ブランチA 大本
def hoge():
print "hoge"

ブランチAで作業中
def hoge():
print "foo"

commit前にブランチAの元に対する修正が来る。
hogeをbarにしてくれ」
つまり、
def bar():
print "bar"
コミットすると自動テストとか走って鬱陶しい


まず、ブランチA上でa.pyというのを作ります。

def hoge():
  print "hoge";

次にa.pyに変更を加えます。commitはしません。

def hoge():
  print "foo";

ここでhogeをbarにする要件変更が来たとしましょう。
git stash saveで状態を保存します。

$ git stash save

次に変更を加える前の、HEADに戻ります。

$ git reset HEAD
$ less a.py
def hoge():
  print "hoge";

ここでhogeをbarに変えていき、commit->pushをします。

$ vi a.py
def foo():
  print "foo";
$ git commit -a
$ git push

ここでまたいっこ前に戻ります。(ここのreset --hard HEADは要見直し)

$ git reset --hard HEAD
$ less a.py
def hoge():
  print "hoge";

ここでgit stash popとやると先ほど編集して一時的に退避してた内容が戻るわけです。

yuki@minatsu:~/tmpclonegit$ git stash pop
# On branch a
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   a.py
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (c4d00b92b4b0b050853192224a08a7f98f12a18f)
$ less a.py
def hoge():
  print "foo"

図にするとこんな感じでしょうか。

得体のしれない改変があって、これをコミットしたくないって時にはいいかもしれません。
ただしその場合改変元のリビジョンには気をつけたほうがよさそうですが(上の例でもgit reset --hard HEADするまえにgit stash popすると残念なことになる)