[エラー解決プロセス説明].gitディレクトリ階下の容量が大きすぎるので小さくしたい

# やりたいこと
ポートフォリオのGitファイルの容量が大きすぎるので小さくしたい。

# 課題
git fetchにやたら時間がかかる。
おそらくGitファイルの容量が大きすぎるのだと思われる。

```
$ git push origin master
Enumerating objects: 232, done. オブジェクトの数を数える
Counting objects: 100% (191/191), done. オブジェクトの数を数える
Compressing objects: 100% (118/118), done. オブジェクトを圧縮する
Writing objects: 100% (134/134), 97.45 MiB | 2.97 MiB/s, done. オブジェクトを書き出す
Total 134 (delta 34), reused 0 (delta 0)
remote: Resolving deltas: 100% (34/34), completed with 23 local objects.
remote: warning: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
大きいファイルが検出されました。Git Large FileStorageを試してみることをお勧めします
remote: warning: See http://git.io/iEPt8g for more information.
remote: warning: File repo/objects/pack/pack-d55b400b67a2428ba4a85b028987d0b7f648c1fc.pack is 97.31 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
これは、GitHubが推奨する最大ファイルサイズである50.00MBよりも大きいです
To github:naota7118/pfc-master.git
```

# エラーログを読み解く

```
remote: warning: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: warning: See http://git.io/iEPt8g for more information.
remote: warning: File repo/objects/pack/pack-d55b400b67a2428ba4a85b028987d0b7f648c1fc.pack is 97.31 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
```
大きなファイルが検出されました。 Git Large FileStorageを試してみることをお勧めします-https：//git-lfs.github.com。
詳細については、http：//git.io/iEPt8gを参照してください。
`repo/objects/pack/pack-d55b400b67a2428ba4a85b028987d0b7f648c1fc.pack`というファイルがめちゃくちゃ大きいようだ。
このファイルはなんだ？

# 解決までの手順
長い記事なので、先にやったことの手順を書いておく。
1. ググって情報収集。
2. `$ du -sh`コマンドという容量を確認するコマンドで`.git`の容量を確認して、`$ git gc --auto`または`$ git gc`という収納するコマンドを使えば.git階下の膨大なデータ量を削減できるとという仮説を立てた。
3. `.git/objects/packfile`が200Mもあり、サイズがデカすぎると知る。
4. packfileは`.git/objects/packfile`だけでなく、`repo/objects/packfile`にも存在することを知る。
5. `.git/objects/packfile`と`repo/objects/packfile`に存在していたpackfileを全て削除した。削除した結果、200Mから500kほどまで削減できた。
6. `$ git push` `$ git pull`で膨大なエラーが表示されるようになった。
7. AWSのEC2で既存のボリュームをデタッチし、新たにボリュームを作りそれをアタッチしたら`$ git push` `$ git pull`が問題なく使えるようになった（[[エラー解決プロセス説明]Gitのpackfileを削除したらgit pushやgit pullできなくなった](https://qiita.com/naota7118/items/e7f4b23b74f664c9cdd8)）

# 考えられる原因
原因を調べるためターミナルの履歴を遡ってみた。

以前`git commit`した時にとてもつもない数のファイルがcreateされている。
これらは何のファイルなんだろう？

```
$ git commit -m"easy login btn application.html.haml"
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
[master ea48fbc] easy login btn application.html.haml
 8945 files changed, 1188646 insertions(+), 1 deletion(-)
 create mode 120000 current
 create mode 100644 releases/20201017104228/.DS_Store
 create mode 100644 releases/20201017104228/.gitignore
 create mode 100644 releases/20201017104228/.rspec
 create mode 100644 releases/20201017104228/.ruby-version
 create mode 100644 releases/20201017104228/.zshrc
 create mode 100644 releases/20201017104228/Capfile
 create mode 100644 releases/20201017104228/Dockerfile
 create mode 100644 releases/20201017104228/Gemfile
 create mode 100644 releases/20201017104228/Gemfile.lock
 create mode 100644 releases/20201017104228/README.md
 create mode 100644 releases/20201017104228/REVISION
 create mode 100644 releases/20201017104228/Rakefile
 create mode 100644 releases/20201017104228/app/.DS_Store
 (ものすごい数なので以下省略)
```
# ログを読み解く
```
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
```
最適なパフォーマンスを得るために、リポジトリをバックグラウンドで自動パックします。
手動のハウスキーピングについては、「githelpgc」を参照してください。

「リポジトリをバックグラウンドで自動パックしてる」ってどういうことだ？

# ググってみる
### ググった結果1
[２年使ってるgitで初めてのエラーメッセージみた](https://www.wegirls.tech/entry/2016/08/16/122842)

```
$ git gc
```

・`$ git gc`garbage collectの略。ゴミ収集のこと。
・不要なオブジェクトをパックファイルの中に入れて削除してくれる。
・不要なオブジェクトを削除するコマンドがあることがわかった。

（追記）
**.git/object/packfile内に入っているのは必ずしも不要なファイルとは限らないかもしれない。**
`$ git gc`は**git log(gitの歴史)関連ファイルを収納してくれるコマンド**であり、**ゴミ収集コマンドでは**ないかもしれない。

というのも、後日.gitのサイズを削減するために、packfile内のフォルダを全て削除したところ、`$ git pull`などのgitコマンドが使えなくなってしまったのだ。
（[[エラー解決プロセス説明]Gitのpackfileを削除したらgit pushやgit pullできなくなった](https://qiita.com/naota7118/items/e7f4b23b74f664c9cdd8)）

packfileは不用意に消さないほうが賢明だ。

### ググった結果2
[10.7 Gitの内側 - メンテナンスとデータリカバリ](https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-%E3%83%A1%E3%83%B3%E3%83%86%E3%83%8A%E3%83%B3%E3%82%B9%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%83%AA%E3%82%AB%E3%83%90%E3%83%AA)

Gitは時々 “auto gc” と呼ばれるコマンドを自動的に実行する。 
いつもはこのコマンドは何もしない。
しかしpackfileがあまりに多い場合は、Gitは完全なgit gcコマンドを起動する。

次のように手動でauto gcを実行することもできる。

```
$ git gc --auto
```

### ググった結果3
[[ Git ] .git/objects/ フォルダの容量削減](https://qrunch.net/@tsuyoshin/entries/YRhnZW1U1cNPFqV5?ref=qrunch)

リポジトリの同期を繰り返し行っていると、gitフォルダの容量が次第に増えてくる。
gitフォルダ内で容量を占めているのは objects フォルダである。

```:GC前の容量確認
$ du -sh .git/objects/  
```

```:GCの実行。不要なファイルが少ない時は実行されない
$ git gc --auto 
```
`$ git gc --auto`で実行されない時はこっちを使う。

```
$ git gc
```

### ググった結果4
[GitのPackfileの容量が増えすぎて、パソコンが身動き取れなくなった日](https://qiita.com/tkw0129/items/73a50355e9bd7fad8705)

同じ問題を抱えている方を見つけた。
この方も相当いろいろな情報から解決されている。

### ググった結果から考察する

ググった結果から、

`$ du -sh .git/objects/`で`.git/objects/`の容量を確認して、`$ git gc --auto `または`$ git gc`して、再び`.git/objects/`の容量を確認すれば良さそう。

しかし、自分の場合pathが`.git/objects/`ではなく`repo/objects/pack/pack-d55b400b67a2428ba4a85b028987d0b7f648c1fc.pack`となっているため、`repo/objects/`としなければならないかもしれない。

# 対策する

1. アプリケーションの本番環境で`$ du -sh .git/objects/`を叩いて`.git/objects/`の容量を確認。
2. .rubocop_todo.ymlをvimか何かで修正する

```
$ du -sh .git/objects/
198M	.git/objects/
```
GC前の容量を確認したところ、198Mだった。
`$ git gc --auto `したが198Mのままだ。

```
$ git gc
fatal: Unable to create '/var/www/rails/pfc-master/.git/gc.pid.lock': No space left on device
```
致命的：`/var/www/rails/pfc-master/.git/gc.pid.lock`を作成できません：デバイスにスペースが残っていません。
不要なファイルを削除しようというのに、スペースが足りないからダメだと言われた。

[追記]
・後日`$ git gc`は不要なファイルを削除するコマンドではなく、**まとめる（収納する）**ためのコマンドだと知った。
・それでもスペースを作るための操作には変わりないのに「スペースが足りないからダメ」と言われるのはなぜだかわからないままだ。

```
自分のアプリのディレクトリから.git/objects/packに移動
$ cd .git/objects/pack
[naota@ip-10-0-0-32 pack]$ ls
pack-498f99382681f8c356c3a0681d130ec483a2b963.idx   pack-6d10ec5b7cc67135161b6a6fcecb8114185a0c1f.pack  pack-facd0ad86270f74705bca9955267fc4284a98ba3.idx
pack-498f99382681f8c356c3a0681d130ec483a2b963.pack  pack-9c040f57a10b527ddd3f788e644b31c7b27988a0.idx   pack-facd0ad86270f74705bca9955267fc4284a98ba3.pack
pack-6d10ec5b7cc67135161b6a6fcecb8114185a0c1f.idx   pack-9c040f57a10b527ddd3f788e644b31c7b27988a0.pack
```

`.git/objects/pack`には8つのpackfileが存在していた。

[[ Git ] .git/objects/ フォルダの容量削減](https://qrunch.net/@tsuyoshin/entries/YRhnZW1U1cNPFqV5?ref=qrunch) 
この記事では、`tmp_pack_xxxxxx`というファイルは`$ git gc`が失敗した時に残ったファイルだから削除しても問題ないと言っている。
しかし、`tmp_pack_xxxxxx`という名前のファイルは存在してない。
packfileは全部消してしまっていいのだろうか？

そもそもpackfileは何かというと、最初に`$ git init`した時に`.git/objects/pack`が作られて、そこに“緩い” （“loose”）オブジェクトが溜められていく。それがpackfile。ゴミ袋のようなものかな？

末尾が`.pack`で終わるpackfileを全部削除したところ、容量が198Mから404Kまで減った。

```
$ du -sh .git/objects/pack
404K	.git/objects/pack
```

これでだいぶ軽量化されたが、今回指摘されたpackfile`repo/objects/pack/pack-d55b400b67a2428ba4a85b028987d0b7f648c1fc.pack`はまだ削除できていない。

それも見に行ってみよう。

```
自分のアプリのディレクトリから.repo/objects/packに移動
$ cd repo/objects/pack
[naota@ip-10-0-0-32 pack]$ ls
pack-0ca3f710576a6f6163a44f01404b45c61cfb6447.idx   pack-3eceb247deb1cecc191c4e2dbef907116a52197d.pack  pack-e97675fa920af589a5ed6707eea4e5945780ad1d.idx
pack-0ca3f710576a6f6163a44f01404b45c61cfb6447.pack  pack-d55b400b67a2428ba4a85b028987d0b7f648c1fc.idx   pack-e97675fa920af589a5ed6707eea4e5945780ad1d.pack
pack-3eceb247deb1cecc191c4e2dbef907116a52197d.idx   pack-d55b400b67a2428ba4a85b028987d0b7f648c1fc.pack
```

```
[naota@ip-10-0-0-32 pfc-master]$ du -sh repo/objects/pack
200M	repo/objects/pack
```

`repo/objects/pack`こっちのpackfileの容量は200M。
`.git/objects/pack`とほぼ同じ容量か。
なぜpackfileが2箇所に作られているんだ？

```
[naota@ip-10-0-0-32 pack]$ rm pack-d55b400b67a2428ba4a85b028987d0b7f648c1fc.pack
rm: 書き込み保護されたファイル 通常ファイル `pack-d55b400b67a2428ba4a85b028987d0b7f648c1fc.pack' を削除しますか?yes
[naota@ip-10-0-0-32 pfc-master]$ du -sh repo/objects/pack
103M	repo/objects/pack
```
指摘されたpackfileを1つ削除しただけで97Mも軽量化できた。
先ほどと同じように末尾が`.pack`のpackfileを全て削除したら420Kまで軽量化できた。

**だいぶサイズが小さくなった。**

```
[naota@ip-10-0-0-32 pfc-master]$ du -sh repo/objects/pack
420K	repo/objects/pack
[naota@ip-10-0-0-32 pfc-master]$ du -sh .git/objects/pack
404K	.git/objects/pack
```

# 当初の問題は解決したが、別の問題が発生した
.gitサイズが大きすぎる問題が解決できたが、`$ git pull`  `$ git push`すると大量のエラーが表示されるようになった。

```
[naota@ip-10-0-0-32 pfc-master]$ git push origin master
error: refs/remotes/origin/Rspec-test does not point to a valid object!
error: refs/remotes/origin/Rspec-unittest does not point to a valid object!
error: refs/remotes/origin/add-weight-to-graph does not point to a valid object!
error: refs/remotes/origin/ajax-comment-function does not point to a valid object!
error: refs/remotes/origin/ajax-favorite-function does not point to a valid object!
error: refs/remotes/origin/auto-change-backgroud-image does not point to a valid object!
error: refs/remotes/origin/automatic-calculation-function does not point to a valid object!
```

`refs/remotes/origin/〜`が有効なオブジェクトを指していないと言われる。
なぜ無効と言われてしまうんだ？

この続きはこちらの記事に書きました。
[[エラー解決プロセス説明]Gitのpackfileを削除したらgit pushやgit pullできなくなった](https://qiita.com/naota7118/items/e7f4b23b74f664c9cdd8)

先にネタバレすると、
AWSのEC2で既存のボリュームをデタッチし、新たにボリュームを作りそれをアタッチすることで、`$ git push` `$ git pull`はできるようになったが、
すでにCapistranoでの自動デプロイまで完了していたのに、unicornを使った手動でAWSへのデプロイをEC2の設定からやり直さなければならなくなったので、
とてもおすすめできる方法ではない。

「.gitファイルが大きすぎる」と言われた場合の、AWSへのデプロイをほぼ1からやり直さず解決する方法を今後も探していきたい。