パスワードなど、特定のファイルを履歴から削除するというのはのはすぐ見つかったが、特定のファイル以外を削除するというのだと見つからなかったのでここに書いておく。
目的
リポジトリ内の特定のディレクトリ(もしくはファイル)を他のリポジトリと共有したい。
そのためにそのディレクトリ(もしくはファイル)のみが含まれるブランチを作りたい。
特定のディレクトリをルートにして別のリポジトリにするならそれ用の
git subtree split
や git filter-branch --subdirectory-filter
があるのだが、今回は切り出したあともcherry-pick
で切り出し元の更新を持ってきたかったので、階層はそのままにしたかった。
結論
切り出し先のブランチを作成、チェックアウトしてから以下を実行する。
※念の為作業用にクローンしてから実行することを推奨
git filter-branch --tree-filter 'ls | grep -v -E "target_dir_or_file" | xargs -r git rm -rf --ignore-unmatch' --prune-empty HEAD
これで今のブランチ(履歴含む)からtarget_dir_or_file
(と.gitignore
を始めとした非表示ファイル)以外のファイルが削除される。切り出し元含む他のブランチはそのままなので、多くの場合既存のブランチとはunrelatedな状態になるはず。
前述の通り非表示ファイルが残っているが、今回は.gitignore
くらいしかなかったので気にしないことにした。