私は現在ローカルのGitリポジトリを持っています。これをGithubリポジトリにプッシュします。
ローカルリポジトリには約10のコミットがあり、Githubリポジトリはこれと同期した複製です。
私がしたいのは、ローカルのGitリポジトリからすべてのバージョン履歴を削除することです。そのため、リポジトリの現在の内容が唯一のコミットとして表示されます(したがって、リポジトリ内の古いバージョンのファイルは保存されません)。
それから私はこれらの変更をGithubにプッシュしたいと思います。
Git rebaseを調べましたが、特定のバージョンを削除するのにより適しているようです。もう一つの可能性のある解決策はローカルレポジトリを削除し、新しいレポジトリを作成することです - これはおそらく多くの作業を生み出すでしょうが!
ETA:追跡されていないディレクトリ/ファイルがあります - 可能であれば、これらのファイルの追跡を維持したいのですが。
これがブルートフォースアプローチです。リポジトリの設定も削除されます。
Note:リポジトリにサブモジュールがある場合、これは機能しません。もしあなたがサブモジュールを使っているなら、あなたは使うべきです。 インタラクティブリベース
手順1:すべての履歴を削除する(バックアップがあることを確認してください。元に戻すことはできません)
cat .git/config # note <github-uri>
rm -rf .git
ステップ2:現在のコンテンツだけでGitリポジトリを再構築する
git init
git add .
git commit -m "Initial commit"
ステップ3:GitHubにプッシュします。
git remote add Origin <github-uri>
git Push -u --force Origin master
私にとって有効な(そしてサブモジュールを機能させ続ける)唯一の解決策は
git checkout --Orphan newBranch
git add -A # Add all files and commit them
git commit
git branch -D master # Deletes the master branch
git branch -m master # Rename the current branch to master
git Push -f Origin master # Force Push master branch to github
git gc --aggressive --Prune=all # remove the old files
私がサブモジュールを持っているとき、.git/
を削除することは常に大きな問題を引き起こします。 git rebase --root
を使うとどういうわけか私に衝突が起こります(そして私はたくさんの歴史を持っているので時間がかかります)。
これは私が支持しているアプローチです。
git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree})
これにより、HEADのすべてを追加する1つのコミットで新しいブランチが作成されます。他に何も変更しないので、完全に安全です。
もう1つの選択肢は、コミットが多い場合には大変な作業になることがありますが、対話的なリベースです(gitのバージョンが1.7.12以上であると仮定した場合)。git rebase --root -i
エディタにコミットのリストが表示されたら:
保存して閉じます。 Gitはリベースを開始します。
最後に、それ以降のすべてのものを組み合わせた新しいルートコミットがあります。
利点は、あなたが自分のリポジトリを削除する必要がないということです、そしてあなたが再考するならば、あなたはいつもフォールバックをするということです。
あなたが本当にあなたの歴史を悪くしたいのなら、masterをこのcommitにリセットし、他のすべてのブランチを削除してください。
larsmans の提案された方法の変形:
未追跡ファイルリストを保存します。
git ls-files --others --exclude-standard > /tmp/my_untracked_files
Gitの設定を保存してください。
mv .git/config /tmp/
その後、larsmansの最初のステップを実行してください。
rm -rf .git
git init
git add .
設定を復元します。
mv /tmp/config .git/
あなたが追跡していないファイルの追跡を解除します。
cat /tmp/my_untracked_files | xargs -0 git rm --cached
次にコミットします。
git commit -m "Initial commit"
そして最後にリポジトリにプッシュします。
git Push -u --force Origin master
浅い クローン (git> 1.9)を使うことができます。
git clone --depth depth remote-url
さらに読む: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/
git filter-branch
は主要手術ツールです。
git filter-branch --parent-filter true -- @^!
--parent-filter
は両親を標準入力に書き出し、書き換えられた両親を標準出力に表示します。 unix true
は正常に終了して何も表示しません。そのため、親はいません。 @^!
は Gitの略です。 「ヘッドコミットはしますが、その親はいません」。それから他のすべての参照を削除して、余暇にプッシュします。
以下の方法は正確に再現可能であるため、両側で一貫性がある場合はcloneを再度実行する必要はありません。反対側でもスクリプトを実行するだけです。
git log -n1 --format=%H >.git/info/grafts
git filter-branch -f
rm .git/info/grafts
その後、それをクリーンアップしたい場合は、このスクリプトを試してください:
http://sam.nipl.net/b/git-gc-all-ferocious
私はリポジトリの各ブランチに対して "履歴を削除する"スクリプトを書きました。
http://sam.nipl.net/b/git-kill-history
また見なさい: http://sam.nipl.net/b/confirm
以下は@Zeelotの答えから改作したスクリプトです。マスターブランチだけでなく、すべてのブランチから履歴を削除する必要があります。
for BR in $(git branch); do
git checkout $BR
git checkout --Orphan ${BR}_temp
git commit -m "Initial commit"
git branch -D $BR
git branch -m $BR
done;
git gc --aggressive --Prune=all
それは私の目的のために働いた(私はサブモジュールを使用していない)。
Githubレポジトリを削除して新しいものを作成するだけです。はるかに速く、最も簡単で安全な方法です。結局、単一のコミットを持つマスターブランチだけが必要な場合に、受け入れられたソリューションでこれらのコマンドをすべて実行する必要がありますか。
私がしたいのは、ローカルのGitリポジトリからすべてのバージョン履歴を削除することです。そのため、リポジトリの現在の内容が唯一のコミットとして表示されます(したがって、リポジトリ内の古いバージョンのファイルは保存されません)。
より概念的な答え:
タグ/ブランチ/参照がそれらを指していない場合、gitは自動的に古いコミットをガベージコレクションします。そのため、単にすべてのタグ/ブランチを削除し、任意のブランチに関連付けられた新しい孤立コミットを作成する必要があります。慣例により、ブランチmaster
にそのコミットをポイントさせることになります。
古くて到達不可能なコミットは、彼らが低レベルのgitコマンドで調べない限り、二度と見られることはありません。それで十分なのであれば、それをやめて、自動GCが望むときはいつでもその仕事をするようにします。すぐにそれらを取り除きたいのなら、git gc
を使うことができます(おそらく--aggressive --Prune=all
と一緒に)。ただし、リモートのgitリポジトリでは、シェルが自分のファイルシステムにアクセスできない限り、それを強制する方法はありません。