大量のファイルをブランチにチェックインしてマージした後、それらを削除する必要がありましたが、今は削除する方法がわからない大きな.packファイルが残っています。
git rm -rf xxxxxx
を使用してすべてのファイルを削除し、--cached
オプションも実行しました。
現在次のディレクトリにある大きな.packファイルを削除する方法を教えてください。
.git/objects/pack/pack-xxxxxxxxxxxxxxxxx.pack
まだ持っているが、もう使用していないブランチを削除するだけですか?または、私が実行する必要がある何か他のものがありますか?
どれだけ違いがあるかはわかりませんが、ファイルに対して南京錠が表示されます。
ありがとう
編集
ここに、bash_historyからの抜粋を示します。これは、この状態に到達する方法を理解するためのものです(この時点で、「my-branch」と呼ばれるgitブランチで作業しており、ファイル):
git add .
git commit -m "Adding my branch changes to master"
git checkout master
git merge my-branch
git rm -rf unwanted_folder/
rm -rf unwanted_folder/ (not sure why I ran this as well but I did)
私はまた、次を実行したと思いましたが、他の人と一緒にbash_historyに表示されません:
git rm -rf --cached unwanted_folder/
また、パックファイルを整理するためにいくつかのgitコマンド(git gc
など)を実行したが、それらは.bash_historyファイルにも表示されないと思った。
問題は、ファイルを削除しても、以前のリビジョンには残っているということです。これがgitの重要なポイントです。何かを削除しても、履歴にアクセスすることで元に戻すことができます。
あなたがやろうとしていることは、履歴の書き換えと呼ばれ、git filter-branch
コマンドが関係していました。
GitHubのサイトでは、この問題に関する適切な説明があります。 https://help.github.com/articles/remove-sensitive-data
質問にもっと直接答えるために、基本的に実行する必要があるのは、それに応じてunwanted_filename_or_folder
を置き換えたこのコマンドです。
git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch unwanted_filename_or_folder' --Prune-empty
これにより、レポのアクティブな履歴からファイルへのすべての参照が削除されます。
次のステップでは、GCサイクルを実行して、ファイルへのすべての参照を期限切れにし、パックファイルから削除します。これらのコマンドで何も置き換える必要はありません。
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --aggressive --Prune=now
シナリオA:大きなファイルがブランチにのみ追加された場合、git filter-branch
を実行する必要はありません。ブランチを削除して、ガベージコレクションを実行するだけです。
git branch -D mybranch
git reflog expire --expire-unreachable=all --all
git gc --Prune=all
シナリオB:ただし、bash履歴に基づいて、変更をマスターにマージしたように見えます。変更を誰とも共有していない場合(まだgit Push
なし)。最も簡単な方法は、大きなファイルがあったブランチとのマージの前にマスターをリセットすることです。これにより、ブランチからのすべてのコミットと、マージ後にマスターに対して行われたすべてのコミットが削除されます。そのため、大きなファイルに加えて、実際に望んでいた変更を失う可能性があります。
git checkout master
git log # Find the commit hash just before the merge
git reset --hard <commit hash>
次に、シナリオAの手順を実行します。
シナリオC:ブランチから他の変更があった場合またはマージ後に保持したい変更がマスターにある場合、マスターをリベースし、選択的にコミットを含めることをお勧めしますあなたが欲しい:
git checkout master
git log # Find the commit hash just before the merge
git rebase -i <commit hash>
エディターで、大きなファイルを追加したコミットに対応する行を削除しますが、その他はすべてそのままにします。保存して終了します。マスターブランチには必要なもののみを含め、大きなファイルは含めないでください。 git rebase
なしの-p
はマージコミットを排除するため、<commit hash>
の後にmasterの線形履歴が残ることに注意してください。これはおそらく大丈夫ですが、そうでない場合は、-p
で試すことができますが、git help rebase
はcombining -p with the -i option explicitly is generally not a good idea unless you know what you are doing
と言います。
次に、シナリオAのコマンドを実行します。
1つのオプション:
git gc
を手動で実行して、多数のパックファイルを1つまたはいくつかのパックファイルに圧縮します。この操作は永続的です(つまり、大きなパックファイルは圧縮動作を保持します)ので、git gc --aggressive
を使用してリポジトリを定期的に圧縮すると有益な場合があります
別のオプションは、コードと.gitをどこかに保存してから.gitを削除し、この既存のコードを使用して再起動して、新しいgitリポジトリ(git init
)を作成することです。
Loganfsmythが answer で既に述べているように、リポジトリからファイルを削除した後もファイルが存在し続けるため、git履歴を消去する必要があります。公式のGitHubドキュメント BFGを推奨filter-branch
よりも使いやすいと思います:
ダウンロード BFGのWebサイトから。 Javaがインストールされていることを確認してから、ミラークローンを作成し、履歴を消去します。 YOUR_FILE_NAME
を削除するファイルの名前に置き換えてください:
git clone --mirror git://example.com/some-big-repo.git
Java -jar bfg.jar --delete-files YOUR_FILE_NAME some-big-repo.git
cd some-big-repo.git
git reflog expire --expire=now --all && git gc --Prune=now --aggressive
git Push
上記と同じですが、--delete-folders
を使用します
Java -jar bfg.jar --delete-folders YOUR_FOLDER_NAME some-big-repo.git
BFGでは、次のようなさらに洗練されたオプション( docs を参照)も使用できます。
履歴から100Mより大きいすべてのファイルを削除します。
Java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git
BFGを実行するときは、YOUR_FILE_NAME
とYOUR_FOLDER_NAME
の両方が実際には単なるファイル/フォルダー名であることに注意してください。 これらはパスではない、したがって、foo/bar.jpg
のようなものは機能しません!代わりに、指定された名前を持つすべてのファイル/フォルダーは、存在するパスまたはブランチに関係なく、レポ履歴から削除されます。
PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
を、ファイル名だけでなく、削除するファイルへのパスに置き換えて、次のコマンドを実行します。これらの引数は:
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA" --Prune-empty --tag-name-filter cat -- --all
これにより、レポのアクティブな履歴からファイルへのすべての参照が強制的に削除されます。
次のステップでは、GCサイクルを実行して、ファイルへのすべての参照を強制的に期限切れにし、パックファイルから削除します。これらのコマンドで何も置き換える必要はありません。
git update-ref -d refs/original/refs/remotes/Origin/master
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --aggressive --Prune=now
私はショーに少し遅れましたが、上記の答えがクエリを解決しなかった場合、別の方法を見つけました。 .packから特定の大きなファイルを削除するだけです。誤って大きな2GBファイルをチェックインしたこの問題がありました。このリンクで説明されている手順に従いました: http://www.ducea.com/2012/02/07/howto-completely-remove-a-file-from-git-history/