tanaka's Programming Memo

プログラミングについてのメモ。

Githubのリポジトリからファイルを削除

Githubに一度コミットしてプッシュしたファイルを削除する手順です。

症状

macGithub公式ツールを使ってコミットしようとしたところ、.gitignoreに登録しているにも関わらず、コミット候補に列挙されるファイルがありました。手動で外しましたが、このままではそのうちうっかりコミットしそうです。過去にコミットしたことがあるファイルはコミット候補に列挙されると思う、というアドバイスをいただき、リポジトリから丸ごとファイルを削除する方法を調べました。

git rmでファイルを削除できますが、過去にコミットした情報は残ります。完全に消し去るには、過去の全てのスナップショットからファイルを削除します。以下、今回やった手順です。

作業用にクローン

現在のフォルダーは最後に統合したいので残しておきます。ファイルを削除する作業をするために、Githubからリポジトリをクローンします。

git clone <コピーしたSSH clone URL>

ブランチを切り替える

  • master以外のブランチで作業をする場合は、以下のように切り替える
git checkout -b <ブランチ名>
git pull origin <ブランチ名>

以上で作業の準備完了です。

履歴からファイルを削除

こちらからの抜粋です。
Git リポジトリに上がっているファイルを履歴ごと消すには? - Qiita
基本的にはこのままで大丈夫です。

以下のコマンドは、現在のブランチの全てのスナップでgit rmを実行するものですので、リポジトリからだけではなく、現在のフォルダーにある消したいファイルも削除されます。

git filter-branch --tree-filter "rm -f [消したいファイルパス]" HEAD
git gc --aggressive --prune=now
git push -f

gitのpush時に「warning: `push.default is unset...`」と表示されたら、以下を参考に設定してください。
git push時に表示されるwarning: `push.default is unset...`の意味と解決方法 - Qiita

Cannot rewrite branches: You have unstaged changes.

ワーキングツリーに変更があると、上記のようなエラーが発生します。git commitやgit pushをして変更を確定させてから、再度、試してください。

Cannot create a new backup

複数のファイルを削除しようとした場合、上記のようなエラーが発生することがあります。その場合は、-fフラグを指定して実行してください。

git filter-branch -f --tree-filter "rm -f [消したいファイルパス]" HEAD

後始末

削除したあとは、リポジトリをcloneし直します。その後、DiffMergeなどのプログラムを利用して、削除前にコピーした元フォルダーと、cloneした新しいフォルダーの中身の違いをチェックして、githubに登録していないファイルをコピーしました。

Githubにプッシュしないファイルは、一箇所にまとめて管理するとよさそうです。


以上です。