gitignoreまとめ

Gitで無視ファイルを細かく設定する際にはまったので、メモ

ヘルプ

こまったら、これで

$ man gitignore

web版

前提

まずは前提を抑えておかないと、はまる

既にトラックされたファイルはgitignoreが効かない
$ git init
$ touch hoge.txt
$ git add hoge.txt # トラックされた後に
$ vim .gitignore # 無視設定しても 
hoge.txt
$ git status # 効かない

既にトラックされたファイルを無視対象にしたければ、git rm --cached

$ git rm --cached hoge.txt # 上記のトラックされたファイルをインデックスから削除すれば(ワークツリーはそのまま)
$ git status #gitignoreが効く

# もしhoge.txtをcommit済みの場合
$ git commit -m 'delete hoge.txt' # コミットしてリポジトリからも消す
空のディレクトリは管理されない
$ git init
$ mkdir aaa # 空のディレクトリを作成
$ git add . 
$ git status # git管理下にならない

Git管理下にしたければ空ファイルを置けばよい。名前は何でもよいが.gitkeepとするのが慣習

$ touch aaa/.gitkeep # 空のディレクトリに.gitkeepという名前の空ファイルを作成
$ git add . 
$ git status # git管理下になる

.gitignore vs .gitkeep
http://stackoverflow.com/questions/7229885/gitignore-vs-gitkeep

優先順位

gitignoreは以下4つの方法で設定できて、それぞれ優先順位がある

↑優先度「高」

(1) コマンドラインからの指定

・git ls-filesなどのコマンドがコマンドラインから無視パターンを指定できる。

<例 >
untrackedなファイルから*.txtにマッチするファイルを除いて表示

$ git ls-files -o --exclude-standard -x '*.txt'
(2) .gitignoreファイル

・プロジェクトのメンバー全員で共通して無視したいパターンに使う。
・通常、バージョンコントロール内に入れてプロジェクトメンバー間でシェアする。
複数の.gitignoreファイルがある場合、階層が深い方が優先される

<例>
.gitignore

*.txt

100/.gitignore

!*.txt

結果

.
├── .gitignore
├── 100/
│   ├── .gitignore
│   └── hoge.txt # 無視しない(100/.gitignoreが適用)
├── 200/
│   └── hoge.txt # 無視する
└── hoge.txt # 無視する
(3) $GIT_DIR/info/excludeファイル

・自分だけの設定。自分がこのプロジェクトにおいてだけ無視したいパターンに使う。
・例えば、自分だけがこのプロジェクトで使っているデバッグ用の俺俺スクリプトなどに。
・$GIT_DIRは、特に設定していなければワークツリーのトップにある.gitディレクトリを指す

<例>

# このプロジェクトに特有な自分だけのスクリプトmy_script.rbをバージョン管理外に
$ vim .git/info/exclude
# git ls-files --others --exclude-from=.git/info/exclude                                                                                                                          
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
my_script.rb
(4) core.excludesfile(設定用変数)で指定されたファイル

・自分だけの設定。自分がどのようなプロジェクトであっても常に無視したいパターンに使う。
・例えば、vimの.swpやmacの.DS_Storeなど

<例>

# git configコマンドで設定(ファイル名は.gitignoreでなくてもよい)
$ git config --global core.excludesfile ~/.gitignore

# すると~/.gitconfigに以下のような記載が追加される
[core]
  excludesfile = /Users/hidenorimaehara/.gitignore

# 対象ファイルに無視パターンを設定
$ vim ~/.gitignore
.DS_Store

↓優先度「低」

無視パターンの書き方

無視パターンの書き方は以下。適用される階層に注意

どこにも/なし

・shell glob pattern(※1)として扱う
・.gitignoreファイルにおいては、その.gitignoreファイルを基準とした相対パスでパターン解析
・つまり、同階層以下全てに適用される(上位階層には適用されない)。
・.gitignoreファイル以外(※2)では、ワークツリーのトップレベル(※3)を基準とした相対パスでパターン解析

<例>
100/.gitignore

*.txt

結果

.
├── 100/
│   ├── .gitignore
│   ├── 110/
│   │   └── hoge.txt #無視する
│   └── hoge.txt #無視する
└── hoge.txt #無視しない(100/.gitignoreの上位階層のため)

※1 http://hgbook.red-bean.com/read/file-names-and-pattern-matching.html#id381291
※2 $GIT_DIR/info/excludeファイルなど
※3 git rev-parse --show-toplevelで確認できる

末尾に/

ディレクトリだけに適用される(ファイルには適用されない)

<例>
100/.gitignore

[0-9][0-9][0-9]/

結果

├── 100/
│   ├── .gitignore
│   ├── 110/ #無視する
│   │   └── hoge.txt
│   ├── 120 #無視しない(120はファイルであり、ディレクトリでないため)
│   └── hoge.txt
└── hoge.txt
先頭に/

・その.gitignoreファイルと同階層にだけ適用される
・「/」はその.gitignoreファイルを基点としたパスのことであり、ファイルシステムのルートではない

<例>
100/.gitignore

/hoge.txt

結果

├── 100/
│   ├── .gitignore
│   ├── 110/
│   │   └── hoge.txt #無視しない(100/.gitignoreの直下ではないため)
│   └── hoge.txt #無視する
└── hoge.txt #無視しない
途中に/

ワイルドカード(*など)が「/」にマッチしないshell glob patternとして解析する
・これは例を見た方がはやい

<例>
100/.gitignore

*/hoge.txt 

結果

├── 100/
│   ├── .gitignore
│   ├── 110/
│   │   ├── 111/
│   │   │   └── hoge.txt #無視しない(100/.gitignoreを基準とした*/hoge.txtに合致しないため)
│   │   └── hoge.txt #無視する
│   └── hoge.txt #無視しない(100/.gitignoreを基準とした*/hoge.txtに合致しないため)
└── hoge.txt #無視しない
!

・逆の意味になる(無視しない)
・これを用いることで、ホワイトリスト方式が実現できる

<例>
.gitignore

# まず直下のファイルとディレクトリを全て無視する                                                                                                                                 
/*

# ただし、以下は無視しない
!/.gitignore
!/100

結果

├── .gitignore #無視しない
├── 100/ #無視しない
│   └── hoge.txt
├── 200/ #無視する
│   └── hoge.txt
├── fuge.txt #無視する
└── hoge.txt #無視する

終わり

Githubには各フレームワークや環境におけるデフォルトのgitignoreが集まっており便利
https://github.com/github/gitignore