.gitignoreについて

`.gitignore`はGitの管理対象から外すためのルールを記述するファイルのこと

注意点としては既にGitに管理(`add`/`commit`)されてしまったものについてはignoreされない。対処法については下のほう。




##.gitignoreの記述方法
例えばこんなディレクトリ階層を考える。

```
/Users/sf213471118/git/test
├ .git
├ .gitignore
├ README.md
├ div.md
├ plan
  └ work
├ hoge.js
├ temp.py
└ work
  ├ hoge.py
  ├ huga.js
  ├ common.jar
  └ work
    └ read.rtf
```

はじめに`.gitignore`は`.git`と同階層に置く。

この`.gitignore`のファイルに管理対象から外すルールを書き込んでいく。

---------




###ディレクトリを無視して除外

例えば階層の異なる`hoge.js`と`hoge.py`の2ファイルを除外するのであれば

```text:.gitignore
hoge.js
hoge.py
```

のように単純にファイル名を列挙すればOK



----------------



###ワイルドカードを用いて除外

`.gitignore`ではワイルドカードが使える。

例えば全てのpythonファイルとhugaを含むファイルを除外するのであれば

```text:.gitignore
*.py
huga*
```

のように記述すればOK

-----------






###ディレクトリを指定して除外

`.gitignore`に記述する条件によっては、条件を満たすignoreしたくないファイルが別階層に存在していることも考えられる。

その場合は`.gitignore`をカレントディレクトリとする相対パスを指定する必要がある。

`.gitignore`と同階層のファイル/ディレクトリを除外したい場合は先頭に`/`をつければOK


+ `work`内のhugaを含むファイル（huga.js）
+ `.gitignore`と同階層のhogeを含むファイル（hoge.js）

上記の2ファイルを除外するのであれば

```text:.gitignore
/work/huga*
/hoge*
```

のように`/`をつけて記述する。




また例えば`read.rtf`が格納されている`work`フォルダのみ無視する場合は

```
/work/work/
```
のように同じく相対パスで記述する必要がある。


よって、以下のように考えることができる

```
#1
work

#2
/work

#3
work/

#4
/work/
```

`#1` --> 全てのworkフォルダが除外される

`#2` --> `.gitignore`と同階層のworkフォルダが除外される

`#3` --> #1と同義

`#4` --> #2と同義


-------------




###ignoreリストから除外する

条件を重ねていくとignoreされたくないファイルまで含まれてしまうことがある。

その場合は先頭に`!`をつけてignoreリストから除外する。

しかし**ディレクトリを無視した場合はその階層以下の特定のファイル/ディレクトリを無視することはできない**という制約がある。


>[git-scm.com](https://git-scm.com/docs/gitignore)
An optional prefix "!" which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined. 

つまり以下のように記述すると、2行目は無視される。

```text:.gitignore
/work/
!/work/common.jar
```

以上のことから、`.gitignore`と同階層の`work`フォルダをignoreするが、`common.jar`のみ残しておきたい時には以下のように記述する

```text:.gitignore
/work/*
!/work/common.jar
```


これであれば、1行目でignoreしたのは**ディレクトリ**ではなく**ファイル/ディレクトリ**である。




こんな感じで`common.jar`だけであれば大丈夫だが、`/work/work/read.rtf`はどうやったら救えるのか。。（汗）

--------







###既に`add`/`commit`したものをignoreする場合


Gitに管理されてしまったものはignoreされないので、その場合は**cache**を削除する必要がある。



```terminal
git rm --cached <file or directory>
```

ファイルを対象とした動作例としてはこんな感じ

```text:terminal
/Users/sf213471118/git/test
$ git rm --cached div.md
rm 'div.md'
```

ディレクトリを対象とする場合は`-r`オプションが必要。動作例としてはこんな感じ


```text:terminal
/Users/sf213471118/git/test
$ git rm -r --cached /work
rm 'work/common.jar'
rm 'work/hoge.py'
rm 'work/huga.js'
```

--------


###gitignoreの動作例

`.gitignore`はこんな感じで、ディレクトリ階層はこのスレッドを全く同じものを想定。

今回のブランチは`master`で進める。

```text:.gitignore
*.md
/plan
*.py
/work/work
!/div*
!/work/hoge*
```

`push`までの流れは以下

```text:terminal
$ git add -A
$ git commit -m "commit .ignore"
[master 0ad845f] commit .ignore
 Committer: sf213471118 <xxxx@xxxx>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

    git config --global user.name "Your Name"
    git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

$ git push
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 4 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 590 bytes | 590.00 KiB/s, done.
Total 6 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 2 local objects.
remote: detect-secrets-stream (beta) ver=151-282d7c1a82922b3275f49f163c77524436ecjfkew FAQ:xxxx
remote: 
remote: Successfully send push metadata.
remote: Push info collect pre-receive hook finished within 3 seconds.
To xxxx:sf213471118/test.git
   52de35b..0sd836a  master -> master
```
流れを見てみると、`push`後に

>Total 6 (delta 3), reused 0 (delta 0)

とあるので、実際にリモートに同期されたのは6ファイルあると確認できた。

元々`.gitignore`の条件を満たすファイルは、

`div.md`,`hoge.js`,`hoge.py`,`huga.js`,`common.jar`

の5ファイルで、これがファーストコミットなので`.gitignore`を加えて6ファイルであると推測できる。

実際にGitHub上で確認が取れたのでこれで無事完了。