4

クライアントをウェブサイトに移行しました。私たちのコードは別のブランチにあり、マスターとリリースにマージされました。Master は、他の機能についても何度か分岐されています。これらのブランチはすべて、Web で見つけた例よりもリポジトリを少し複雑にします。

クライアントの元のメディア (主に画像と大きな CSV ファイル) も Git にチェックインされていることがわかりました。わずか 12MB 程度ですが、削除する理由はいくつかあります (特に、クライアントのファイル名に非 ASCII 文字が含まれているため、OSX 上の Vagrant ボックスの共有フォルダーとうまく機能していません)。リポジトリのサイズの内訳は次のとおりです。

$ du --max-depth 1 -h
12M  ./.git
13M  ./modules
2.0M ./themes
27M  .

バイナリは明らかに複数のブランチに存在しますが、私が知る限り、次のようにして両方のバイナリを削除し、次にそれらに対応するリポジトリ オブジェクトを削除できるはずです。

$ git filter-branch --tree-filter "git rm -rf --ignore-unmatch modules/custom/mymigration/data/photos/*" # Did this with and without "HEAD" argument
[snip lots of output]
$ git reflog expire --expire=now --all 
$ git gc --aggressive --prune=now

ただし、まだ大きな .git サブフォルダーがあります。

$ du --max-depth 1 -h
12M  ./.git
1.4M ./modules
2.0M ./themes
15M  .

最大のファイルは .git/objects/pack/pack-....pack です。これについて .idx ファイルを確認すると、次のようになります。

$ git verify-pack -v .git/objects/pack/pack-53c8077d0590dabcf5366589c3d6594768637f5e.idx | sort -k 3 -n | tail -n 5

オブジェクトの長いリストを取得します。これを rev-list にパイプし、移行データ ディレクトリを grep すると、次のようになります。

$ for i in `git verify-pack -v .git/objects/pack/pack-53c8077d0590dabcf5366589c3d6594768637f5e.idx | sort -k 3 -n | tail -n 5 | awk '{print $1}'`;    do 
    git rev-list --objects --all | \
      grep $i | \
      grep modules/custom/mymigration/data
  done
47846536601f0bc3a31093c88768b522a5500c96 modules/custom/mymigration/data/photos/Turkey.jpg
b920e36357d855352f4fdb31c17772d21c01304d modules/custom/mymigration/data/photos/Burger_Top.JPG

ご覧のとおり、写真はまだパックファイルにあります。

  • このリポジトリを (完全に空の) リモートにプッシュし、そのリモートをまったく別の場所に複製すると、まだ 12MB のパック ファイルが残っています。
  • このリポジトリをローカルに複製してgit clone file://path/to/old-repos new-reposも同じ効果があります。さらに悪いことに、すべての元のブランチが消えて (おそらく予想されるように)、master しかありません。

これらのパックされたオブジェクトを取り除くためにできることはありますか? それらが非常に継続的に存在していることは、それらがまだどこかの git commit オブジェクトに関連付けられていることを示唆していますか? しようとしましrepackprune-packedが、何も変わりませんでした。

さらに、最初のビットを適切に実行しないと、「それらを取り除く」だけで何かが壊れる可能性がありますか? git commit がまだ参照しているファイル オブジェクトが削除されるとどうなりますか?

4

2 に答える 2

7

以下は繰り返し機能し、リポジトリを約 2.5MB .git と合計 5.8MB に削減します。上記の@jamessanによる提案が含まれています。

これにより、すべてのブランチからオブジェクトが削除され、それらの削除がリモート リポジトリにプッシュされます。そのリモート リポジトリは、私が知る限り、これらのオブジェクトから完全に解放されています (リポジトリのサイズが劇的に減少しています)。

# Configure the repository to push all existing branches & tags
# when none are explicitly specified
git config --add remote.origin.push '+refs/tags/*:refs/tags/*'
git config --add remote.origin.push '+refs/heads/*:refs/heads/*'

# Make sure all local branches exist, so they get filtered
for remote_branch in `git branch --all | grep -v HEAD | sed -e 's/\*//'`; do local_branch=`echo $remote_branch | sed -e 's!remotes/origin/!!'`; git checkout $local_branch; done

# Prevent git <1.7.7.1 from complaining about dirty working directory
git update-index -q --ignore-submodules --refresh

# Do the filtering across --all branches and rewrite tags
# Note that this will necessarily remove signatures on tags
git filter-branch -f --tree-filter "git rm -rf --ignore-unmatch modules/custom/mymigration/data/photos/*" --tag-name-filter cat -- --all

# Remove the backed-up refs
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d

# Clear out the reflog and garbage-collect
git reflog expire --expire=now --all
git gc --aggressive --prune=now

# Push all changes to origin - pushes tags and branches
git push origin
于 2012-05-17T10:16:02.627 に答える
2

git-filter-branch の man ページの下部には、リポジトリを縮小する 2 つの方法が説明されています。

簡単な方法は、リポジトリを再度クローンすることです

git clone file:///path/to/repo

より複雑なアプローチは、あなたがしたこと(reflogの期限切れ、gc)に似ていますが、最初のステップを省略しました

git-filter-branch によってバックアップされた元の参照を削除します: git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d

于 2012-05-16T16:02:02.037 に答える