リポジトリのサイズを減らす
Bitbucket はソース ファイルの保管や変更の管理に最適で、チームでの作業の際にはそのメリットをさらに発揮します。しかしながら、実行ファイルやその他のビルド アーティファクト、動画、その他のメディア ファイルなどの、大規模なバイナリ ファイルの保管には適していません。
弊社のサーバーでユーザーに十分な応答性やダウンロード速度を提供するためにも、リポジトリ サイズを 1.0 GB にすることを推奨しています。Bitbucket Cloud のリポジトリには 2.0 GB の制限があります。この制限に到達した場合、直前のコミットを取り消すための変更のプッシュのみを行えます。また、5.0 GB のハード制限があります。この制限に到達した場合、変更をプッシュすることはできず、リポジトリは読み取り専用になります。
Bitbucket で大規模なファイルを保持する必要がある場合、ワークフローの一環として Git Large File Storage (Git LFS) を導入し、BFG を使用してリポジトリを Git LFS に移行することをご検討ください。
リポジトリのサイズ制限
これらの制限をサイズが上回った場合、[リポジトリの詳細] パネルに警告が表示されます。
1.0 GB の制限を上回った場合
1.0 GB の制限を上回っている場合、コミットをプッシュすると、コマンド ラインに次のような警告が表示されます。
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 332 bytes | 332.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: This repository is currently 1.0 GB in size. If it exceeds 2 GB it will be put into read-only mode.
remote: Learn how to reduce your repository size: https://confluence.atlassian.com/x/xgMvEw
To https://bitbucket.org/example/monster.git
3db4505..0393b72 master -> master
$ _
この警告が表示された場合、リポジトリのメンテナンスを行って大規模なファイルを削除してください。詳細については後述の「大規模なファイルを削除する」をご参照ください。
2.0 GB の制限を上回った場合
サイズが 2.0 GB の制限を上回っている場合、以降はコミットをプッシュすることはできません。
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 406 bytes | 406.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: b'Repository is over the size limit (2 GB) and will not accept further additions.
remote:
remote: Learn how to reduce your repository size: https://confluence.atlassian.com/x/xgMvEw.
remote: '
To https://bitbucket.org/example/monster.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://user@bitbucket.org/example/monster.git'
$ _
引き続き変更を行うには、直前のコミットを取り消す必要があります。後述の「最後のプッシュを取り消す」をご参照ください。これにより、サイズを 2.0 GB 制限よりも小さくし、プッシュ制限を解除して、リポジトリのメンテナンスを行うことができます。
5.0 GB の制限を上回った場合
5.0 GB を上回った場合、すべての変更が却下されます。サポート リクエストを起票して、リポジトリのサイズを縮小するための支援を依頼する必要があります。
最後のプッシュを取り消す
大規模なファイルを削除するには、履歴を書き換える必要があります。これを行わない場合、Git は大規模なファイルを履歴で保持します。
この手順を実行する前に、サイズ制限を超える場合に不要なコミットを削除する機能を Labs で有効にして、ガベージ コレクションを自動的にトリガーすることができます。
これにより、ブランチの先頭に巻き戻す際に履歴から大規模ファイルが削除され、サポート リクエストを送信する必要がなくなります。
履歴を巻き戻して大規模なコミットを取り消す
悪影響を与えているコミットを含むブランチをその 1 つ前のコミットに巻き戻し、直前のコミットを取り消して、リポジトリ サイズを制限未満にします。このプロセスでは、悪影響を与えているコミットが 1 つのコミットにのみ存在し、ほかのブランチにマージされていないと仮定しています。
影響を受けるブランチを使用しているすべてのユーザーに、直前のコミットを取り消すことを伝え、そのコミットをほかのブランチにマージしないように依頼する必要があります。
Bitbucket のリモート履歴は、以下の例のようになります。
branch
|
o---o---o---o <= last (bad) commit in Bitbucket
ローカル履歴は、取り消しが必要なコミットが 1 つのみの場合は以下の例のようになります。
branch
|
o---o---o---o---o <= last local commit failed to push
|
reset to here and push
悪影響を与えるコミットを含むブランチで履歴を巻き戻すには、次の操作を実行します。
任意のローカル コミットを保持するための一時ブランチを作成します。
元のブランチを、大規模なファイルを含み悪影響を与えるコミットの直前のコミットにリセットします。
新しい head を Bitbucket にプッシュします (履歴の書き換え)。
ローカルでの変更を復元します。これらはまだプッシュできません。まず大規模なファイルを削除する必要があります。
git branch <keeper>
git reset --soft @{u}^
git push --force
git merge --ff-only <keeper>
git branch -d <keeper>
--soft
オプションを使用することで、未プッシュのすべてのコミットと、未コミットのすべての変更を保持できます。これにより、大規模ファイルの削除が完了したら、それらをあとでプッシュできます。保持したい変更がない場合、上述のコマンド ラインの例で --hard
オプションを使用し、ステップ 1、4、および 5 をスキップしてかまいません。
ガベージ コレクションを実行して不要なコミットを削除する
Labs 機能を有効にした場合 (前述のヒント参照)、悪影響を与えるコミットが自動ガベージ コレクションで削除され、リポジトリ サイズが数分で縮小されます。
この機能を有効化していない場合、ガベージ コレクションを実行して、履歴から消去された悪影響を与えるコミットを削除し、リポジトリのサイズを縮小するには、サポート リクエストを起票する必要があります
Bitbucket のリモート履歴は、以下の例のようになります。
branch
|
o---o---o-/-o
|
dangling commit deleted
これが完了したらプッシュを行えるようになるため、大規模なファイルを削除してリポジトリ サイズを 1.0 GB の制限未満に減らすことができます。後述の「大規模ファイルの削除」をご参照ください。
大規模ファイルの削除
プッシュ制限が解除されたら、リポジトリから大規模なファイルを削除できます。Git リポジトリのメンテナンスや Git LFS の使用の詳細について、次のリソースをご利用いただけます。
Git リポジトリの管理 – Git リポジトリから大規模ファイルを削除する方法
BFG を使用してリポジトリを Git LFS に移行する – プランで Git LFS を使用する方法
追加の LFS ストレージを支払うことなく大量の大規模ファイルを保持したい場合、それらを別の場所に保持する必要があります。利用可能なオプションの一部については「大規模ファイルの保管オプション」をご参照ください。
大規模ファイルを削除したら、リポジトリを使用しているすべてのユーザーが新しいクローンを作成することをおすすめします。これを行わない場合、ほかのユーザーが強制プッシュを行ったときに大規模ファイルが再度プッシュされ、作業をやり直す必要があります。
大規模なコミットの回避
大規模なファイルを意図せずリポジトリに追加することを防ぐための方法として、いくつかのものが考えられます。
含めたくないファイルを無視するように Git で設定する
自動化を導入して大規模なコミットの作成を防止する
大規模なファイルの無視
ローカル リポジトリを含むディレクトリの .gitignore
ファイルに pathname パターンを追加することで、コミットからファイルを除外するように Git に設定できます。
例:
# File types to ignore
*.exe
*.bin
*.jar
*.war
*.mp3
*.mp4
# Directories to ignore
target/
.build/
.env/
一般に、次のようなデータを無視するように Git に設定します。
ビルド アーティファクト – これらはディレクトリに保管することをおすすめします。たとえば、Maven はこれらを
target
ディレクトリに保管します。IDE 設定 – これらは通常、リポジトリには不要です。たとえば、
.idea
ディレクトリを無視します。依存関係 – 依存関係のキャッシュを除外します。例として、Python の vitrualenv や node のローカル パッケージがあります。
メディア ファイル – git リポジトリは大規模な音声または動画ファイルの保管には推奨されません。
大規模なコミットのブロック
大規模なファイルがコミットに含まれるのを防ぐために、各コミットのファイル サイズを確認するローカル フックをインストールして、サイズが大きすぎる場合はコミットを却下できます。
check_added_large_files フックから開始します。これをリポジトリにコピーして、すべてのユーザーが自身のローカル リポジトリでコミット前のフックとして追加できるようにします。
ln -s check_added_large_files.py .git/hooks/pre-commit.py
スクリプトのコピーは、リポジトリ内で要件に併せて自由に変更できます。各ユーザーはプルを行ったときに最新のロジックを受信します。
大規模ファイルの保管オプション
Bitbucket リポジトリは、ソース ファイルの保管に最適です。ソースから生成された他のファイルには、それらに適した保管場所を用意することをおすすめします。次のような例があります。
アーティファクト リポジトリの使用
ビルド アーティファクトを保管する多数のサービスがあります。一般的な 2 つの例は次のようなものです。
ビルド プロセスを構成し、ビルド アーティファクトをこれらのリポジトリにアップロードして共有できるようにします。また、ビルド アーティファクトをコミットから除外するように .gitignore
が構成されていることを確認します。
Docker リポジトリの使用
Bitbucket リポジトリを実行ファイルのビルドに使用している場合、それらを Docker イメージとしてビルドすることをご検討ください。
ビルド プロセスでイメージを Docker Hubにホストされた Docker リポジトリやローカルの Docker リポジトリにプッシュすることができます。
AWS S3 の使用
大規模なメディア ファイルを Bitbucket リポジトリに保管するのではなく、簡単にダウンロード可能な S3 バケットにアップロードすることができます。
Git LFS の使用
ファイルが Bitbucket リポジトリに必要不可欠の場合、ご利用のプランで利用可能な Large File Storage を使用します。必要に応じてストレージを追加購入できます。
ワイルドカード パターンを使用して、特定のタイプのファイルには LFS を使用するように Git を設定します。
git lfs track "<pattern>"
MP4 動画 LFS を使用する場合、次のようになります。
git lfs track "*.mp4"
* 上述の例の引用符は重要です。
より効率性の高い Large File Storage に既存の大規模ファイルを移動することで、BFG を使用してリポジトリを Git LFS に移行し、リポジトリのサイズを減らして Bitbucket エクスペリエンスを改善できます。