これを行う1つの方法は、逆です。保持するファイル以外のすべてを削除します。
基本的に、リポジトリのコピーgit filter-branch
を作成してから、保持するファイル/フォルダ以外のすべてを削除するために使用します。
tvnamer.py
たとえば、ファイルを新しいリポジトリに抽出したいプロジェクトがあります。
git filter-branch --tree-filter 'for f in *; do if [ $f != "tvnamer.py" ]; then rm -rf $f; fi; done' HEAD
これはgit filter-branch --tree-filter
、各コミットを実行し、コマンドを実行して、結果のディレクトリコンテンツを再コミットするために使用されます。これは非常に破壊的であり(したがって、リポジトリのコピーでのみこれを行う必要があります!)、しばらく時間がかかる場合があります(300コミットと約20ファイルのリポジトリで約1分)
上記のコマンドは、リビジョンごとに次のシェルスクリプトを実行するだけです。もちろん、これを変更する必要があります(代わりにサブディレクトリを除外するためtvnamer.py
)。
for f in *; do
if [ $f != "tvnamer.py" ]; then
rm -rf $f;
fi;
done
最大の明らかな問題は、残りのファイルとは無関係であっても、すべてのコミットメッセージが残ることです。スクリプトgit-remove-empty-commitsは、これを修正します。
git filter-branch --commit-filter 'if [ z$1 = z`git rev-parse $3^{tree}` ]; then skip_commit "$@"; else git commit-tree "$@"; fi'
(基本的にはバックアップ)にあるものを使用して、 -f
force引数をfilter-branch
再度実行する必要があります。refs/original/
もちろん、これは決して完璧ではありません。たとえば、コミットメッセージに他のファイルが記載されている場合ですが、(とにかく私が知っている限りでは)gitcurrentが許す限り近いです。
繰り返しますが、これはリポジトリのコピーでのみ実行してください。-しかし、要約すると、「thisismyfilename.txt」以外のすべてのファイルを削除するには:
git filter-branch --tree-filter 'for f in *; do if [ $f != "thisismyfilename.txt" ]; then rm -rf $f; fi; done' HEAD
git filter-branch -f --commit-filter 'if [ z$1 = z`git rev-parse $3^{tree}` ]; then skip_commit "$@"; else git commit-tree "$@"; fi'