hogehoge foobar Blog Style Beta

Web,Mac,Linux,JavaScript,Perl,PHP,RegExp,Git,Vim,Redmineなど技術的なことのメモや、ちょっと便利そうなものの紹介をしています。

git addでステージングしたファイルをアンステージング(キャンセル)する

git add を実行あとで修正していなかった部分に気づいてしまった場合や、
「git add .」で間違って.swpとかのバックアップファイルがステージングに入ってしまった場合に、
git addをキャンセルする方法です。

コマンドの構文

ファイルをキャンセルする場合
git rm --cached ファイル名
ディレクトリをキャンセルする場合
git rm -r --cached ディレクトリ名

git rmは、Working Tree (作業コピー)と index からファイルを削除するコマンドですが、 --cachedを指定する事で、 indexからのみファイルを削除する事ができます。

http://blog.s21g.com/articles/960

指定する、ファイル名やディレクトリ名にはワイルドカード(*.swp等)が使用できます。

間違って要らないファイルをgit addしてしまった!

間違って、*.swpファイルもgit addでステージングに含めてしまいました。

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   bar.txt.swp
#       new file:   foo.txt.swp
#       new file:   hogedir/hoge.txt
#       new file:   hogedir/hoge.txt.swp

「git rm --cached *.swp」で「*.swp」ファイルのgit addをキャンセルします。

$ git rm --cached *.swp
rm 'bar.txt.swp'
rm 'foo.txt.swp'

「hogedir/」配下のhoge.txt.swpがキャンセルされていないので個別にキャンセルします。

$ git rm --cached hogedir/hoge.txt.swp
rm 'hogedir/hoge.txt.swp'

git statusでステージングの状態を確認すると、hogedir/hoge.txtだけがnew fileとしてステージングに登録されています。

$ git status
# On branch Branch_5bd1c1db81db4363005fdbc358d8638b7f1bdc61
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   hogedir/hoge.txt
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       bar.txt.swp
#       foo.txt.swp
#       hogedir/hoge.txt.swp

あとはいつも通りgit commitを行えば、hogedir/hoge.txtだけがコミットされます。

$ git commit -m "commit message."
[Branch_5bd1c1db81db4363005fdbc358d8638b7f1bdc61 a24f498] commit message.
 1 files changed, 11 insertions(+), 0 deletions(-)
 create mode 100644 hogedir/hoge.txt

「git rm -r --cached .」はちょっと危険?

git addしたものを一括で取り消そうと思って、「git rm -r --cached .」というコマンドを実行してしまうと、git addしていないファイル(下記ではbar.txtとfoo.txt)までもがrmされてしまいます。

$ git rm -r --cached .
rm 'bar.txt'
rm 'bar.txt.swp'
rm 'foo.txt'
rm 'foo.txt.swp'
rm 'hogedir/hoge.txt'
rm 'hogedir/hoge.txt.swp'

git statusでステージングを確認すると、git addしていないファイル(bar.txtとfoo.txt)が「deleted: bar.txt」のように表示され、次回のコミットで削除される形になってしまいます。
実際にこのままgit commitするとファイルが削除された状態でコミットされてしまいました。

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       deleted:    bar.txt
#       deleted:    foo.txt
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       bar.txt
#       bar.txt.swp
#       foo.txt
#       foo.txt.swp
#       hogedir/

ということで、「git rm -r --cached」はできるだけ個別にファイル名やディレクトリ名を指定するのが安全なようです。

あと、「*.swp」や「*~」のようなバックアップ系のファイルは.gitignoreでgitでの管理対象外にしてしまって、本当にgit addを間違えた時だけ、今回のコマンドを使用するのが良い使い方だと思います。。

今回参考にしたページ

gitで不要なaddを取り消す方法 - mumoshu.log
http://d.hatena.ne.jp/mumoshu/20090408/1239202846

Gitで間違えたgit addをキャンセルする方法 - Hello, world! - s21g
http://blog.s21g.com/articles/960

Git 使い方アレコレ - NINXIT-BLOG
http://www.ninxit.com/blog/2009/09/28/git-%E4%BD%BF%E3%81%84%E6%96%B9%E3%82%A2%E3%83%AC%E3%82%B3%E3%83%AC/