web-dev-qa-db-ja.com

古いgit履歴を削除する方法は?

私は、多くの(2000以上の)コミットを含むgitリポジトリを持っています。例えば:

                 l-- m -- n   
                /
a -- b -- c -- d -- e -- f -- g -- h -- i -- j -- k
                     \
                      x -- y -- z

そして、古いログ履歴を切り捨てたい-コミット「f」から始まるが、リポジトリの開始としてログ履歴からすべてのコミットを削除します。

どうやってするの?

19
Nips

歴史を失わないために。最初にリポジトリのコピーを取得することをお勧めします:)。ここに行きます:(<f>は、新しいルートコミットにしたいコミットfのshaです)

git checkout --Orphan temp <f>      # checkout to the status of the git repo at commit f; creating a branch named "temp"
git commit -m "new root commit"     # create a new commit that is to be the new root commit
git rebase --onto temp <f> master   # now rebase the part of history from <f> to master onthe temp branch
git branch -D temp                  # we don't need the temp branch anymore

同じ切り捨てられた履歴を保持したいリモートがある場合; git Push -fを使用できます。 警告これは危険なコマンドです。これを軽く使用しないでください!コードの最後のバージョンが同じであることを確認したい場合。 git diff Origin/masterを実行できます。変更は表示されません(履歴のみが変更され、ファイルのコンテンツは変更されていないため)。

git Push -f  

次の2つのコマンドはオプションです-gitリポジトリを良好な状態に保ちます。

git Prune --progress                 # delete all the objects w/o references
git gc --aggressive                  # aggressively collect garbage; may take a lot of time on large repos
32
Chris Maes

git clone オプションを使用して --shallow-since を実行すると、問題の解決策が提供されます。 f以降のコミット数が少なく、それらのカウントに問題がない場合は、 --depth オプションを使用できます。

2番目のオプション(--depth)は、指定されたブランチのみを複製します。追加のブランチが必要な場合は、元のリポジトリをリモートとして追加し、 git fetch を使用してそれらを取得できます。

結果に満足したら、古いリポジトリを削除し、新しいリポジトリの名前を変更して置き換えます。古いリポジトリがリモートの場合は、削除してから新しいリポジトリからプッシュして再作成します。

このアプローチには、サイズと速度という利点があります。新しいレポジトリには必要なコミットのみが含まれ、古いオブジェクトを削除するためにgit Pruneまたはgit gcを実行する必要はありません(存在しないため)。

12
axiac