Reduce repository size

リポジトリが 2 GB の制限に達してしまいましたか。

深呼吸をしてください。本ページの最初の手順にしたがえば、正常の動作状態に復帰できます。

いったん 2 GB の制限を超えてしまうと、プッシュした コミットの削除または打消ししかできず、新しいコミットはプッシュできません。

1 GB のソフト リミットを超えた場合、またはリポジトリのサイズを縮小したい場合

本ページにたどり着いた理由が、すでに 1 GB のソフト リミットを超えたため、またはコンパクトで効果的なリポジトリを維持したいだけである場合、最初のセクションはとばしてもかまいません。本ページの残りの部分では、以下の内容について説明します。

  • Bitbucket 上のリポジトリのサイズを確認する。
  • Git または Mercurial からファイルを削除すると、リポジトリの履歴にどのような影響を与えるか理解する。
  • 望みの結果を得るの​​に役立つ保守手順を選択し、実行する。

 

 

リポジトリ制限の削除

この手順によって、リポジトリからプッシュ制限を削除できます。ただし、完全に問題を解決するには、この手順を完了したあと、本ページに記載する保守手順のどれかをさらに選択する必要があります。

開始する前に、リポジトリをバックアップしましょう! バックアップを作成する最も簡単な方法は、--mirror フラグを使用してリポジトリをクローンし、クローン全体を圧縮するやり方です。

リポジトリをメンテナンスすることについて、チームまたはリポジトリのフォロワーに伝えます 。履歴を書き換えることになるので、実行しようとしていることを全員に周知してください。チームへの連絡は不可欠であり、それが礼儀です。

次の最初のステップをすべて自分で完了して、Bitbucket にプッシュバックします。

  1. Pull the latest version of your repository from Bitbucket using the git pull --all command.
  2. メンテナンス中にファイル損失の可能性があっても回復できるように、リポジトリをローカルでバックアップします。
  3. Run the git log command with -n 4  from your terminal. The number after the -n determines the number of commits in the log starting from the most recent commit in your local history.

    $ git log -n 4 

    このコマンドにより、直近の 4 コミットが次のように表示されます。

    $ git log -n 4
    commit 86833d553529f99aad975539b03edce333bd4108
    Merge: b8b6122 d446c3b
    Author: Dan Stevens [Atlassian] <dstevens@atlassian.com>
    Date:   Fri Dec 4 14:09:41 2015 -0800
    
        Merged in dstevens/review2 (pull request #9)
        
        Adding add-on context and connect descriptor pages to the nav and concepts section
    
    commit d446c3bb361339c2c6aedb85b38c20959da8e345
    Author: Daniel Stevens <dstevens@atlassian.com>
    Date:   Fri Dec 4 13:52:33 2015 -0800
    
        revising scopes and context section to remove bad definition and provide links to complete scopes section.
    
    commit c78869f36fd93bd7ad82d7bdd86f779ef08d3f11
    Author: Daniel Stevens <dstevens@atlassian.com>
    Date:   Wed Dec 2 17:13:41 2015 -0800
    
        changing JSON file to JSON object in introduction
    
    commit c1b0c56b1a7aa69d80581a61c9ac45129efadc4f
    Author: Daniel Stevens <dstevens@atlassian.com>
    Date:   Wed Dec 2 16:28:32 2015 -0800
    
        Fixing definition of account context to reflect the truth about when it is visible
  4. Reset the head of your repository's history using the git reset --hard HEAD~N where N is the number of commits you want to take the head back. In the following example the head would be set back one commit, to the last commit in the repository history:

    このように HEAD をリセットし、次のステップで変更を強制的にプッシュすることにより、コミット(複数可)内のすべての変更が完全に削除されます。これは破壊的な操作なので、先​​に進む前に、追加したファイルはすべてバックアップします。

    git reset --hard HEAD~1

  5. Push the change to Bitbucket using git push --force to force push the change.

    git push --force 

    Once you push your changes Bitbucket will automatically run an aggressive git gc (git garbage collection) to rewrite the history and reflect your change. Wait a few moments for the system to run the change. If we haven't removed the limitation after 60 minutes and you want to keep troubleshooting, choose one of the methods on this page and do a more complete maintenance on your repository.

    If you've reduced the repository size locally and made a force push and still have a limitation after 60 minutes, you can contact support to run a git gc on the server for you.

ヒント Sketch で作成されました。

再度リポジトリがハード リミットに達しないようにするため、また、1 GB のソフト リミットを削除するためには、本ページの 1 つ以上の手順を使用して、リポジトリで完全な保守サイクルを実施します。

Bitbucket リポジトリ制限

すべてのユーザーに最善かつ最速のサービスを提供するため、リポジトリを次のサイズに制限しています。

  • ソフト リミット1 GB :この時点で、効果的に動作するリポジトリのサイズ上限に達しつつあることを知らせます。ハード リミットに達しないように保守を実行することが必要な場合があります。 
  • ハード リミット2 GB :これは実質的にリポジトリ サイズのストップサインで、リポジトリのサイズを縮小するまで、実行可能な操作を制限します。

リポジトリが 2 GB の制限を超えた場合

ローカル リポジトリを縮小する手順を実施し、Bitbucket に変更をプッシュした後は、aggressive Git gc を自動的に実行してクリーンアップし、作業の再開を可能にします。

Bitbucket リポジトリのサイズ調査

Bitbucket のリポジトリの相対的なサイズを確認するには、設定をクリックし、開いたリポジトリの詳細ページでサイズ行を探します。

  1. リポジトリの詳細: このページにリポジトリ サイズが表示されます。
  2. 設定: 左側のパネルにこのリンクが表示されます。
  3. サイズ: 各リポジトリの名前の下に、それぞれのサイズが表示されます。
ヒント Sketch で作成されました。

理想的には、リポジトリ サイズを 100 MB と 300 MB の間に維持するのがよいでしょう。例をあげると、Git 自体は 222MB、Mercurial 自体は 64MB、Apacheは 225MB あります。これらのオープンソースのリポジトリは次のサイトで確認できます。 https://bitbucket.org/mirror/

Git リポジトリのサイズをコマンドラインで調べる

コマンドラインを使用して、ローカルシステム上のリポジトリのサイズを調べることができます。

Git の場合、次のコマンドを使用します。

git count-objects -v 

このコマンドにより、次のような結果が返されます。

$ git count-objects -v 
count: 0
size: 0
in-pack: 478
packs: 1
size-pack: 92
prune-packable: 0
garbage: 0

size-pack 値はリポジトリが Bitbucket などのリモート サーバーにプッシュされたときのサイズです。size-pack 値はキロバイト単位です。  したがって、上記の例のリポジトリは 1MB もありません。  

ローカルの Mercurial リポジトリのサイズをコマンドラインで調べる

Mercurial にはリポジトリのサイズを調べる特別のコマンドがありません。bundle コマンドを使用して、リポジトリの圧縮ファイルを生成すると、以下の例に示すように、ファイルのサイズ(約 21.658MB)を確認できます。

$ hg bundle --all my-bundle.hg
2474 changesets found
$ ls -al my-bundle.hg 
-rw-r--r--  1 manthony  staff  21658140 Feb 10 15:03 my-bundle.hg

Git リポジトリでのファイル削除を理解する

リポジトリの履歴書き換えは慎重を要する作業です。というのは、すべてのコミットがその親に依存し、どんな小さな変更であっても、以降のすべてのコミットのコミット ID を変更するためです。この作業用に 2 つの自動化ツールが利用できます。

  1. BFG Repo Cleaner - 処理が速く、シンプルで使いやすい。Java 6 以上が必要です。
  2. git filter-branch - 強力ではあるが、設定が難しく、規模の大きいリポジトリの場合、処理が遅い。 コア Git スイートの一部です。

Remember, after you rewrite the history, whether you use the BFG or filter-branch, you will need to remove reflog entries that point to old history, and finally run the garbage collector to purge the old data.

 

履歴を書き換えると、コミット id が変更されます。その結果、変更された id のコミットを参照するプルリクエストは、それらのコミットとコメントに関する情報を失います。

プルリクエストの履歴を保持したい場合は、リポジトリのクリーン バージョンを、既存のリポジトリではなく新しく作成したリポジトリにプッシュすることをお勧めします。

Git 履歴書き換えのしくみ

リポジトリのクローンにより、すべてのソースコード ファイルのすべてのバージョンを含めて、履歴全体のクローンが作成されます。ユーザーが JAR など規模の大きいファイルをコミットする場合、その後で作成するすべてのクローンにこのファイルが含まれます。その後のコミットでプロジェクトから該当のファイルを削除することになったとしても、ファイルは依然としてリポジトリ履歴内に存在します。 リポジトリと履歴からこのファイルを削除するには、次の作業が必要です。

  • プロジェクトの現在のファイルツリーからファイルを削除する
  • リポジトリ履歴からファイルを削除する - Git 履歴を書き換え、履歴を含むすべてのコミットをファイルから削除する
  • 古いコミット履歴を参照する reflog 履歴をすべて削除する
  • リポジトリをリパックし、git gc を使用して、現在は使用していないデータをガーベジコレクトする

Git 「GC」(ガベージ コレクション)は、どのブランチやタグも実際に使用せず、何らの参照もしていないすべてのデータをリポジトリから削除します。ガベージ コレクションを有効にするには、不要ファイルを含むリポジトリ履歴をすべて書き換えて、不要ファイルを参照しないようにする必要があります。これで git gc は現在使用されていないデータを破棄できるようになります。

BFG による履歴の書き換え

BFG は大規模ファイルやパスワードなど、不要なデータを Git リポジトリから削除することを目的とする特別のツールで、(現在のコミットに含まれない)サイズの大きい履歴を簡単に削除する「--strip-blobs-bigger-than」フラグを備えています。

$ java -jar bfg.jar --strip-blobs-bigger-than 100M

(BFG により最新のコンテンツが保護されているため、最新 のコミットに含まれない) サイズが 100MB 以上のファイルは Git リポジトリの履歴から削除されます。必要であれば、ファイル名による指定も可能です。

$ java -jar bfg.jar --delete-files *.mp4

BFG は git filter-branch より 10 倍~ 1000 倍速く、一般的にずっと使いやすいツールです。詳細については、詳しい使用方法使用例を確認してください。

git filter-branch による履歴書き換え(代替方法)

The filter-branch command rewrites a Git repo's revision history, just like the BFG, but the process is slower and more manual. If you don't know where the big file is, your first step will be to find it using one of the two following options:

そのあと、ファイルを一つずつ削除するか、特定のブランチを削除するか決める必要があります。どちらにしても、処理を完了するには、Git ガベージコレクションを実行する必要があります。 

手作業によってリポジトリ内の大規模ファイルを確認する

Antony Stubbs はこの作業を効率的に実行する BASH スクリプトを書きました。 このスクリプトはパックファイルの内容を調べ、大規模ファイルを一覧表示します。ファイルの削除を開始する前に、次の操作を行い、このスクリプトを入手してインストールします。

  1. ローカル システムにスクリプトをダウンロードします。
  2. Git リポジトリにアクセス可能な、既知の場所にスクリプトを置きます。
  3. スクリプトを実行可能にします。

    $ chmod 777 git_find_big.sh
  4. ローカルシステムにリポジトリのクローンを作成します。
  5. リポジトリのルート ディレクトリに移動します。
  6. Git ガベージコレクタを手動で実行します。

    git gc --auto
  7. .git フォルダーのサイズを調べます。

    $ du -hs .git/objects
    45M	.git/objects 

    あとで参照するために、このサイズを書きとめます。

  8. List the big files in your repo by running the git_find_big.sh script.

    $ git_find_big.sh 
    All sizes are in kB's. The pack column is the size of the object, compressed, inside the pack file.
    size  pack  SHA                                       location
    592   580   e3117f48bc305dd1f5ae0df3419a0ce2d9617336  media/img/emojis.jar
    550   169   b594a7f59ba7ba9daebb20447a87ea4357874f43  media/js/aui/aui-dependencies.jar
    518   514   22f7f9a84905aaec019dae9ea1279a9450277130  media/images/screenshots/issue-tracker-wiki.jar
    337   92    1fd8ac97c9fecf74ba6246eacef8288e89b4bff5  media/js/lib/bundle.js
    240   239   e0c26d9959bd583e5ef32b6206fc8abe5fea8624  media/img/featuretour/heroshot.png

    The big files are all JAR files.  The pack size column is the most relevant.  The aui-dependencies.jar compacts to 169KB  but the emojis.jar compacts only to 580.  The emojis.jar is a candidate for removal.

filter-branch を実行する

The filter-branch command can contain task specific filters for rewriting the Git index.  For example, a filter can remove a file from every indexed commit.  The syntax for this is the following:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch pathname' commitHASH
  • The --index-filter option modifies a repo's staging (or index).
  • The --cached option removes a file from the index not the disk.  This is faster as you don't have to checkout each revision before running the filter. 
  • The --ignore-unmatch option in git rm prevents the command from failing if the pathname it is trying to remove isn't there. 
  • By specifying a commit HASH, you remove the pathname from every commit starting with the HASH on up.  To remove from the start, leave this off or you can specify HEAD.  

大規模ファイルが別々のブランチにある場合は、ファイルごとに名前を指定して削除する必要があります。すべてのファイルが 1 つのブランチ内にある場合は、ブランチ自体を削除します。

名前指定による削除

以下の手順により、大規模ファイルを削除します。

  1. 次のコマンドを(ファイル名 指定部分に実際のファイル名を入力して)実行し、特定した最初の大規模ファイルを削除します。

    git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
  2. 残りの大規模ファイルごとに、手順 1 を繰り返します。

  3. Update the references in your repository. filter-branch creates backups of your original refs namespaced under refs/original/. Once you're confident that you deleted the correct files, you can run the following command to delete the backed up refs, allowing the large objects to be garbage collected:

    $ git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d

ブランチそのものの削除

すべての大規模ファイルが 1 つのブランチ内にある場合は、ブランチを削除するだけですみます。ブランチの削除により、すべての参照が自動的に削除されます。

  1. ブランチを削除します。

    $ git branch -D branch-name
  2. 削除したブランチからの無効な reflog 参照のすべてを削除します。

    $ git reflog expire --expire=now branch-name

不要データのガベージ コレクト

  1. (1 つのブランチのみを明示して作業している場合を除き)現在削除ずみのデータからの無効な reflog 参照をすべて削除します。

    $ git reflog expire --expire=now --all
  2. ガベージコレクタを実行し、古いオブジェクトを削除して、リポジトリをリパックします。

    $ git gc --prune=now
  3. すべての変更を Bitbucket リポジトリにプッシュバックします。

    $ git push --all --force
  4. タグもすべてカレントであることを確認します。

    $ git push --tags --force

Mercurial のリポジトリを縮小する方法 

Mercurial リポジトリのサイズを縮小するには、定期的なメンテナンスが必要です。他のバージョン管理システムからコードをインポートした場合、インポート後に不要なファイルをクリーンアップする必要があります。ここでは Mercurial リポジトリから大規模ファイルを削除することにより、リポジトリのサイズを縮小する方法について説明します。

リポジトリのサイズを縮小するもう一つの方法は、リポジトリを複数の小さなリポジトリに分割することです。この方法はリポジトリ内のディレクトリごとに実行可能で、ディレクトリごとにサブリポジトリを作成します。リポジトリの分割に関する詳細については、リポジトリの 2 分割 を参照してください。

大規模ファイルを見つける方法

大規模ファイルとは、一般的にサードパーティ製のライブラリ(jar ファイル、dll ファイル)、アプリケーションのコンパイル済みバージョン、(画像ファイルのような)バイナリ形式のメディア資産などです。通常、Mercurial はファイルの差分を保存するので、注意が必要です。バイナリ ファイルの内容を少し変更すると、多くのファイル、または大半のファイルでバイト数が変わる可能性があります。バイナリ ファイルに変更をコミットすることにより、Mercurial が大規模なファイルの全体または大半を複数回保存する可能性があります。  

Linux 環境の場合

Linux 環境で大規模ファイルを検索するには、次のパイプ コマンドを使用します。

$ find . -type f \( ! -regex ".*/\..*" \) -print | xargs ls -l | sort -k5,5rn | head

This command ignores hidden files and directories. For example, the command ignores everything in the the .hg directory.  It sorts the output of the ls by size and uses the head command to return the ten largest files. For example, right now the Bitbucket tutorial repo has these large files:

-rwxr-xr-x  1 manthony  staff  548107 Feb 12 11:18 ./yearone.html
-rw-r--r--  1 manthony  staff  205672 Feb 12 11:18 ./images/mahmoud-darwish.gif
-rw-r--r--  1 manthony  staff  155848 Feb 12 11:18 ./images/so_many_activities.jpg
-rw-r--r--  1 manthony  staff  149472 Feb 12 11:18 ./images/EleanorRoosevelt.png
-rw-r--r--  1 manthony  staff  122251 Feb 12 11:18 ./images/AmbroseBierce.gif
-rw-r--r--  1 manthony  staff  112894 Feb 12 11:18 ./javascripts/foundation.js
-rw-r--r--  1 manthony  staff  109986 Feb 12 11:18 ./images/Deep-Thought.png
-rw-r--r--  1 manthony  staff   88873 Feb 12 11:18 ./images/AlbertEinstein.png
-rw-r--r--  1 manthony  staff   88387 Feb 12 11:18 ./images/willferrell.png
-rw-r--r--  1 manthony  staff   87721 Feb 12 11:18 ./images/NeilTysonOriginsA-FullSize.jpg

Windows 環境の場合

Windows 環境では、PowerShell を使用することを推奨します。Windows 7 で PowerShell を開くには、次の操作を行います。

  1. スタート ボタンをクリックします。
  2. Begin typing Powershell in the Search programs and files field.
  3. Windows PowerShell オプションを選択します。
    PowerShell コマンド ウィンドウが開きます。 
  4. リポジトリのルートに変更します。
  5. コマンドプロンプトで次のように入力します。

    gi -Path .\* -Exclude .hg | gci -r -ea 0 | sort Length -desc | select -f 10

    This command lists all the repo's files excluding those in the .hg (metadata) directory. The system lists output similar to the following:

        Directory: C:\Users\manthony\Documents\tutorials
    
    Mode                LastWriteTime     Length Name
    ----                -------------     ------ ----
    -a---         3/25/2013  10:00 AM     548107 yearone.html
    
        Directory: C:\Users\manthony\Documents\tutorials\images
    
    Mode                LastWriteTime     Length Name
    ----                -------------     ------ ----
    -a---         3/25/2013  10:00 AM     205672 mahmoud-darwish.gif
    -a---         3/25/2013  10:00 AM     155848 so_many_activities.jpg
    -a---         3/25/2013  10:00 AM     149472 EleanorRoosevelt.png
    -a---         3/25/2013  10:00 AM     122251 AmbroseBierce.gif
    
        Directory: C:\Users\manthony\Documents\tutorials\javascripts
    
    Mode                LastWriteTime     Length Name
    ----                -------------     ------ ----
    -a---         3/25/2013  10:00 AM     112894 foundation.js
    
        Directory: C:\Users\manthony\Documents\tutorials\images
    
    Mode                LastWriteTime     Length Name
    ----                -------------     ------ ----
    -a---         3/25/2013  10:00 AM     109986 Deep-Thought.png
    
        Directory: C:\Users\manthony\Documents\tutorials
    
    Mode                LastWriteTime     Length Name
    ----                -------------     ------ ----
    -a---         3/25/2013  10:00 AM      91116 index.html
    
        Directory: C:\Users\manthony\Documents\tutorials\images
    
    Mode                LastWriteTime     Length Name
    ----                -------------     ------ ----
    -a---         3/25/2013  10:00 AM      88873 AlbertEinstein.png
    -a---         3/25/2013  10:00 AM      88387 willferrell.png

大規模ファイルの削除

To remove large files, you use the convert extension and --filemap option.  The convert extension filters a repository and creates a new repository with a parallel history. The  --filemap option takes a filemap file that specifies filters for file processing.   During the conversion process the convert extension uses the filemap to modify the changesets it processes. You can use the filemap to include, rename, or exclude individual files or whole directories.

For example, the following shows a simple set of filemap directives:

# Comment
include path/to/file
exclude path/to/file
rename from/file to/file

For the detailed information about the convert extension and the --filemap option, see the ConvertExtension --filemap documentation.

変換によってリポジトリのファイルを縮小する例

次のようなディレクトリ構造のリポジトリを考えてみましょう。

repo
│─ doc
│─ commons-collections-3.2.1-javadoc.jar
│─ commons-io-2.0.1-javadoc.jar
└─ commons-lang-2.6-javadoc.jar
│─ lib
│─ commons-collections-3.2.1.jar
│─ commons-io-2.0.1.jar
└─ commons-lang-2.6.jar
└─ src
│─ commons-collections-3.2.1-sources.jar
│─ commons-io-2.0.1-sources.jar
└─ commons-lang-2.6-sources.jar

To remove all libraries except commons-lang and retain all Javadoc except the one for commons-io you create the following filemap.txt file in the repository root:

include "repo"
exclude "repo/lib"
include "repo/lib/commons-lang-2.6.jar"

# the following include is optional
include "repo/doc"
exclude "repo/doc/commons-io-2.0.1-javadoc.jar"

次に、構造を変換するには、コマンドラインで次のコマンドを発行します。

hg convert --filemap filemap.txt initialHgRepo hgRepoAfterConversion

initialHgRepo is the repository to convert and the hgRepoAfterConversion is the new repository.  After the conversion, hgRepoAfterConversion repository structure is:

repo
│─ doc
│─ commons-collections-3.2.1-javadoc.jar
└─ commons-lang-2.6-javadoc.jar
│─ lib
└─ commons-lang-2.6.jar
└─ src
│─ commons-collections-3.2.1-sources.jar
│─ commons-io-2.0.1-sources.jar
└─ commons-lang-2.6-sources.jar

You can then check in the hgRepoAfterConversion repository.

ファイル削除によるリポジトリ サイズの維持

使わないファイルを削除するのは、リポジトリのサイズを縮小するいい方法です。ファイルを削除しても履歴から削除されませんが、リポジトリの現在のバージョンを縮小します。古いファイルを取得する必要がある場合、どのクローン​​にもそのファイルが残っています。削除するべきファイルとして、次の項目を検討します。

  • SQL ダンプ
  • 大規模なメディア資産
  • アプリケーションのコンパイル済みバージョン
  • サードパーティ製のライブラリと依存性(jar、dll、gem など)
  • 履歴内の完全に不要な大規模ファイル

バイナリ ファイルは常に削除候補となります。DVCS システムは、バイナリ ファイルを格納するのに適しているとは言えません。Drive、Dropbox、Carbonite などのファイル ホスティング サービスにファイルをホスティングすることを検討するとよいでしょう。

プロジェクト リポジトリへのリポジトリの分割

コード プロジェクトごとにリポジトリを分割することにより、リポジトリのサイズを縮小できます。これには、プロジェクト間の相互参照状況を理解しておく必要があります。たとえば、大規模リポジトリ内に相互参照がない 4 つのプロジェクトがある場合、これを 4 つの小規模なリポジトリに分割できます。  

リポジトリを分割する手順については、リポジトリの 2 分割 を参照してください。


最終更新日 2017 年 6 月 28 日

この内容はお役に立ちましたか?

はい
いいえ
この記事についてのフィードバックを送信する
Powered by Confluence and Scroll Viewport.