[解決済み] git リポジトリの履歴を折りたたむ
質問
私たちは、かなり大きな履歴を持つgitプロジェクトを持っています。
特に、プロジェクトの初期には非常に多くのバイナリリソースファイルがありましたが、これらは事実上外部リソースであるため、現在では削除されています。
しかし、これらのファイルを以前にコミットしたため、リポジトリのサイズは >200MB (現在の総チェックアウトは ~20MB) になっています。
私たちが行いたいことは、リポジトリが実際よりも遅いリビジョンから作成されたように見えるように、履歴を "collapse"することです。たとえば、次のようになります。
1-----2-----3-----4-----+---+---+
\ /
+-----+---+---+
- リポジトリ作成
- 大量のバイナリ ファイルが追加されました。
- 削除された大量のバイナリ ファイル
- リポジトリの新しい意図された「開始」。
つまり、ある時点より前のプロジェクトの履歴を失いたいのです。この時点ではブランチは 1 つだけなので、複数の開始点を扱うような複雑なことはありません。しかし、すべての履歴を失い、現在のバージョンで新しいリポジトリを開始したくはありません。
これは可能ですか、それとも私たちは永遠に肥大化したリポジトリを持つ運命にあるのでしょうか?
どのように解決するのですか?
バイナリの肥大化を取り除き、残りの履歴を維持することができます。Git では、以前のコミットを並べ替えたり「つぶしたり」することができるので、大きなバイナリ ファイルを追加したり削除したりするコミットだけを結合することができます。追加を一つのコミットで、削除を別のコミットで行った場合、それぞれのファイルを扱うよりずっと簡単でしょう。
$ git log --stat # list all commits and commit messages
これを検索して、あなたのバイナリファイルを追加・削除したコミットを探し、その SHA1 を記録します。
2bcdef
と
3cdef3
.
次に、レポの履歴を編集するために
rebase -i
コマンドの interactive オプションで、バイナリを追加したコミットの親から始めてください。これで $EDITOR が起動し、以下のコミットのリストが表示されます。
2bcdef
:
$ git rebase -i 2bcdef^ # generate a pick list of all commits starting with 2bcdef
# Rebasing zzzzzz onto yyyyyyy
#
# Commands:
# pick = use commit
# edit = use commit, but stop for amending
# squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
pick 2bcdef Add binary files and other edits
pick xxxxxx Another change
.
.
pick 3cdef3 Remove binary files; link to them as external resources
.
.
挿入
squash 3cdef3
を2行目として挿入し、以下の行を削除します。
pick 3cdef3
という行をリストから削除します。 これで、対話型アクションのリストができました。
rebase
は、バイナリを追加したり削除したりしたコミットをひとつのコミットにまとめ、その diff にはそれらのコミットでの変更点をそのまま反映させます。そして、完了を告げると、それ以降のすべてのコミットを順番に再適用します。
$ git rebase --continue
これは1〜2分かかります。
これで、バイナリが出入りすることのないリポジトリができました。 しかし、バイナリはまだスペースを取っています。デフォルトでは、Git は変更をゴミ箱に回収する前に 30 日間保持するので、気が変わったら削除することができます。
もし、今すぐ削除したいのであれば
$ git reflog expire --expire=1.minute refs/heads/master
#all deletions up to 1 minute ago available to be garbage-collected
$ git fsck --unreachable # lists all the blobs(files) that will be garbage-collected
$ git prune
$ git gc
これで、肥大化した部分を削除しましたが、残りの履歴は残しました。
関連
-
[解決済み] Git で直近のローカルコミットを取り消すには?
-
[解決済み] Gitブランチをローカルやリモートで削除するには?
-
[解決済み] git pull」と「git fetch」の違いは何ですか?
-
[解決済み] コミット前に 'git add' を取り消すにはどうすればよいですか?
-
[解決済み] リモートのGitブランチをチェックアウトするには?
-
[解決済み] Git リポジトリを以前のコミットに戻すにはどうすればよいですか?
-
[解決済み] 現在のGit作業ツリーからローカル(未追跡)ファイルを削除する方法
-
[解決済み] Git で、ステージされていない変更を破棄するにはどうしたらいいですか?
-
[解決済み】"git pull" でローカルファイルを強制的に上書きするには?
-
[解決済み】ローカルのGitブランチの名前を変更するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
致命的 リモートレフマスターが見つからない
-
git push は最新の解決策を提供します。
-
コミットには何も追加されないが、未追跡のファイルが存在する解決策
-
git push issues
-
[解決済み] gitにもsvnのような無視コマンドはありますか?
-
[解決済み] なぜGitでコミットする前にステージが必要なのですか?
-
[解決済み] チェリーピックのコンフリクトを解決するにはどうしたらいいですか?
-
[解決済み] ローカルのGitブランチをリモートレポにコピーする方法
-
[解決済み] CVS から Git への移行: $Id$ 相当?
-
[解決済み] git add --patch' で新しいファイルをインクルードする?