Githubに100MB以上のファイルをプッシュする方法

# はじめに
- GitHubでは100MB以上のファイルをプッシュすると拒否され、50MB以上のファイルをプッシュすると警告される仕組みとなっています。
- 今回はGitHubに100MB以上のファイルをプッシュする方法を考えてみたいと思います。


# Githubに100MB以上のファイルをプッシュする方法

- 100MB以上のファイルをそのままプッシュするとGithubに拒否されてしまうため、ファイルを分割してプッシュしようと思います。
- また、50 MBより大きいファイルを追加または更新しようとすると、Githubから警告が表示されるので、49MBでファイル分割しようと思います。
- 具体的には、ZIPファイルをbase64にエンコードして、49MBのテキストファイルに分割してプッシュします。
- 元のファイルに戻すときは、分割したテキストファイルのテキストを結合して、デコードすればZIPファイルに戻ります。

# 実装
Pythonで実装したコードが以下です。

### フォルダ構成
```
ディレクトリ
├─main.py
├─setting.json
├─input
└─output
```

### コード
```python:main.py
import base64
import json
import glob


def split_text(text, split_byte_size, charcode='utf-8'):
    bytes_text = text.encode(charcode)
    head = bytes_text[:split_byte_size].decode(charcode, errors='ignore')
    tail = text[len(head):]

    if tail == text:
        return []

    split_tail = split_text(tail, split_byte_size)

    result = []
    result.append(head)
    result.extend(split_tail)

    return result


if __name__ == "__main__":
    # 設定取得
    setting = json.load(open('./setting.json', "r", encoding="utf-8"))
    if setting["setting"] == "z2t":
        input_path = str(setting["input"]) + "in.zip"
        with open(input_path, "rb") as f:
            s = base64.b64encode(f.read())
        split_text = split_text(s.decode(), int(setting["byte"]))
        for index, text in enumerate(split_text):
            f = open(str(setting["output"]) + "file" + str(index) + ".txt", 'w', encoding=setting["encoding"])
            f.write(text)
            f.close()
    elif setting["setting"] == "t2z":
        file_txt = ""
        for index, filepath in enumerate(glob.glob(str(setting["input"]) + "*")):
            with open(str(setting["input"]) + "file" + str(index) + ".txt", "r", encoding=setting["encoding"]) as f:
                file_txt += f.read()
        output_path = str(setting["output"]) + "out.zip"
        with open(output_path, "wb") as f:
            f.write(base64.b64decode(file_txt))
```

```json:setting.json
{
  "setting": "z2t",
  "encoding": "shift_jis",
  "input": "./input/",
  "output": "./output/",
  "byte": "51380224",
  "コメント": "setting：zipファイルをテキストファイルに変換する際は「z2t」、テキストファイルをzipファイルに変換する際は「t2z」、encoding：文字コード、inputは入力対象ディレクトリのパス、outputは出力対象ディレクトリのパス、byte：テキストファイル出力時の分割サイズ、ファイル名：「in.zip」または「in.txt」"
}
```

# 使い方
- 使い方は `setting.json` の中身を書き換えて使用します。
    - `setting` ：zipファイルをテキストファイルに変換する際は「`z2t`」、テキストファイルをzipファイルに変換する際は「`t2z`」
    - `encoding` ：文字コード
    - `input` ：入力ディレクトリパス
    - `output` ：出力ディレクトリパス
    - `byte` ：分割するバイト数
- ZIPファイルをテキストファイル分割する場合は、`input` のディレクトリパスに「`in.zip`」という名前で保存する。
- 分割されたテキストファイルをZIPファイルに戻す場合は、`input` のディレクトリパスに全てのテキストファイルを配置する。

### ZIPファイル ⇒ テキストファイル
1. ZIPファイルを「`in.zip`」という名前で `input` のディレクトリパスに配置する。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/894d0a78-8389-71ea-a462-3c5cb9a4eda2.png)
2. `setting.json` の `setting` の値を `z2t` にする。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/7851a5ac-0428-fe2c-8bee-12768c3c672b.png)
3. `main.py` を実行する。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/7a225225-4ff4-3413-089f-945951ba61ca.png)
4. `output` のディレクトリパスにテキストファイルができていれば成功。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/681e168d-d34f-4580-40b8-c68486fa12dc.png)
5. 作成されたテキストファイルをGitHubにプッシュする。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/4be9dd06-f623-8a3c-17f4-8728bf15915b.png)

### テキストファイル ⇒ ZIPファイル
1. GitHubからテキストファイルを落としてくる。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/4be9dd06-f623-8a3c-17f4-8728bf15915b.png)
2. テキストファイルを `input` のディレクトリパスに配置する。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/681e168d-d34f-4580-40b8-c68486fa12dc.png)
3. `setting.json` の `setting` の値を `t2z` にする。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/029889cf-0964-df27-e2cb-91815f1ee33a.png)
4. `main.py` を実行する。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/7a225225-4ff4-3413-089f-945951ba61ca.png)
5. `output` のディレクトリパスに「`out.zip`」ができていれば成功。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/17b69815-b59d-0663-70b2-1f63b2cf0de5.png)

# GitHub
GitHubにソースコードを公開しています。

https://github.com/ryomeblog/qiita/tree/master/Githubに100MB以上のファイルをプッシュする方法