Cover Image for .gitignore に記載されているファイルをリポジトリの歴史から削除する

.gitignore に記載されているファイルをリポジトリの歴史から削除する

この記事は最終更新日から7年以上が経過しています。

経緯

JavaのプロジェクトをSVNからGitに移行する際に元のリポジトリにコミットされていたjar,warなどのバイナリを消したかった。 もっと良いやり方があったら教えて下さい。

方法

.gitignoreが存在するディレクトリで以下2コマンドを実行

grep -v '^\s*#' .gitignore | grep -v '^\s*$' | grep -v '/' | grep -v '^!' |awk '{print "git filter-branch -f --tree-filter \047find . -name " $0 " | xargs rm -rf \047 HEAD --all"}' | sh

grep -v '^\s*#' .gitignore | grep -v '^\s*$' | grep '/' | grep -v '^!' | awk '{print "git filter-branch -f --tree-filter \047rm -rf " $0 "\047 HEAD --all"}' | sh

解説

ファイルの場合

grep -v '^\s*#' .gitignore | grep -v '^\s*$' | grep -v '/' | grep -v '^!' |awk '{print "git filter-branch -f --tree-filter \047find . -name " $0 " | xargs rm -rf \047 HEAD --all"}' | sh
  • .gitignoreから空白行とコメント行を除いた行を取得
  • そこからスラッシュ(ディレクトリ)を含む行と、!で開始されている行(例外設定)を除外
  • 取得した行に対してawkでgitコマンドを生成
    • ファイルなのでfindで探してrmしている
  • パイプでshに渡して実行

ディレクトリの場合

grep -v '^\s*#' .gitignore | grep -v '^\s*$' | grep '/' | grep -v '^!' | awk '{print "git filter-branch -f --tree-filter \047rm -rf " $0 "\047 HEAD --all"}' | sh
  • .gitignoreから空白行とコメント行を除いた行を取得
  • そこからスラッシュ(ディレクトリ)を含む行を抽出、!で開始されている行(例外設定)を除外
  • 取得した行に対してawkでgitコマンドを生成
    • ディレクトリなのでそのままrmしている
  • パイプでshに渡して実行

参考