Git プロジェクトを GitHub に置きたいのですが、機密データ (capistrano の /config/deploy.rb などのユーザー名とパスワード) を含む特定のファイルが含まれています。
これらのファイル名を.gitignoreに追加できることはわかっていますが、Git 内の履歴は削除されません。
また、/.git ディレクトリを削除してやり直したくありません。
Git 履歴から特定のファイルの痕跡をすべて削除する方法はありますか?
Git プロジェクトを GitHub に置きたいのですが、機密データ (capistrano の /config/deploy.rb などのユーザー名とパスワード) を含む特定のファイルが含まれています。
これらのファイル名を.gitignoreに追加できることはわかっていますが、Git 内の履歴は削除されません。
また、/.git ディレクトリを削除してやり直したくありません。
Git 履歴から特定のファイルの痕跡をすべて削除する方法はありますか?
すべての実用的な目的のために、最初に心配する必要があるのは、パスワードの変更です! あなたの質問からは、あなたの git リポジトリが完全にローカルなのか、それともリモート リポジトリがまだ別の場所にあるかどうかは明らかではありません。それが離れていて、他の人から保護されていない場合、問題があります。これを修正する前に誰かがそのリポジトリのクローンを作成した場合、彼らはローカル マシンにあなたのパスワードのコピーを持っていることになり、履歴から削除された「修正済み」バージョンに強制的に更新することはできません。唯一できる安全な方法は、パスワードを使用したすべての場所で別のパスワードに変更することです。
それが邪魔にならないように、これを修正する方法を次に示します。GitHub はまさにその質問に FAQ として答えました:
Windows ユーザーへの注意: このコマンドでは、シングルの代わりに二重引用符 (") を使用し ます。
git filter-branch --index-filter \
'git update-index --remove PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA' <introduction-revision-sha1>..HEAD
git push --force --verbose --dry-run
git push --force
2019年更新:
これは、FAQ からの現在のコードです。
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA" \
--prune-empty --tag-name-filter cat -- --all
git push --force --verbose --dry-run
git push --force
このコードを GitHub などのリモート リポジトリにプッシュし、他の人がそのリモート リポジトリのクローンを作成すると、履歴を書き換えている状態になることに注意してください。この後、他の人があなたの最新の変更を取り込もうとすると、早送りではないため変更を適用できないというメッセージが表示されます。
これを修正するには、既存のリポジトリを削除して再クローンするか、 git-rebase manpageの「RECOVERING FROM UPSTREAM REBASE」の指示に従う必要があります。
ヒント:実行git rebase --interactive
将来、機密情報を含むいくつかの変更を誤ってコミットしたが、リモート リポジトリにプッシュする前に気付いた場合は、いくつかの簡単な修正方法があります。最後のコミットが機密情報を追加するものである場合は、単に機密情報を削除してから実行できます。
git commit -a --amend
これにより、以前のコミットが、git rm
. 変更履歴がさらにさかのぼってもリモート リポジトリにプッシュされていない場合は、インタラクティブなリベースを実行できます。
git rebase -i origin/master
これにより、リモート リポジトリとの最後の共通の祖先以降に行ったコミットを含むエディターが開きます。機密情報を含むコミットを表す行で「pick」を「edit」に変更し、保存して終了します。Git は変更を順を追って説明し、次のことができる場所に移動します。
$EDITOR file-to-fix
git commit -a --amend
git rebase --continue
機密情報を含む変更ごとに。最終的にはブランチに戻り、新しい変更を安全にプッシュできます。
パスワードを変更することは良い考えですが、リポジトリの履歴からパスワードを削除するプロセスについては、BFG Repo-Cleanergit-filter-branch
をお勧めします。これは、Git リポジトリからプライベート データを削除するために明示的に設計されたものよりも高速でシンプルな代替手段です。
削除するパスワードなどをリストしたファイルを作成しprivate.txt
(1 行に 1 エントリ)、次のコマンドを実行します。
$ java -jar bfg.jar --replace-text private.txt my-repo.git
リポジトリの履歴でしきい値サイズ (デフォルトでは 1MB) 未満のすべてのファイルがスキャンされ、一致する文字列 (最新のコミットにないもの) は文字列 "***REMOVED***" に置き換えられます。git gc
その後、デッド データを消去するために使用できます。
$ git gc --prune=now --aggressive
BFG は通常、実行よりも 10 ~ 50 倍高速でgit-filter-branch
あり、オプションは簡素化され、次の 2 つの一般的なユースケースに合わせて調整されています。
完全な開示: 私は BFG Repo-Cleaner の作成者です。
GitHub にプッシュした場合は、強制プッシュでは不十分です。リポジトリを削除するか、サポートに連絡してください
以下に説明するように、1 秒後に強制的に押しても十分ではありません。
有効な行動方針は次のとおりです。
パスワードのような変更可能な資格情報が漏洩したのは何ですか?
はい: パスワードをすぐに変更し、OAuth キーと API キーの使用を検討してください。
いいえ (裸の写真):
リポジトリ内のすべての問題が核攻撃されても気にしますか?
いいえ: リポジトリを削除します
はい:
次の理由により、1 秒後に押すだけでは十分ではありません。
GitHub は、長い間コミットをぶら下げ続けます。
ただし、GitHub スタッフは、連絡があれば、そのようなダングリング コミットを削除する権限を持っています。
GitHub のすべてのコミット メールをレポジトリにアップロードしたとき、私はこれを直接経験しましたgc
。ただし、データを含むプル リクエストは削除する必要があります。これにより、そのレポ データは最初の削除から最大 1 年間アクセス可能でした。
ダングリング コミットは、次のいずれかで確認できます。
そのコミットでソースを取得する便利な方法の 1 つは、任意の参照を受け入れることができるダウンロード zip メソッドを使用することです。
次のいずれかの方法で、不足している SHA を取得できます。
type": "PushEvent"
。私の例: https://api.github.com/users/cirosantilli/events/public ( Wayback machine )http://ghtorrent.org/やhttps://www.githubarchive.org/のようなスクレイパーがあり、定期的に GitHub データをプールして別の場所に保存しています。
彼らが実際のコミットの差分をスクレイピングしているかどうかはわかりませんでした。データが多すぎるため、それはありそうにありませんが、技術的には可能であり、NSA とその友人は、人々や関心のあるコミットにリンクされたものだけをアーカイブするフィルターを持っている可能性があります。
ただし、強制的にプッシュするのではなく、リポジトリを削除すると、API からでもコミットがすぐに消えて 404 が表示されます。同じ名前で別のリポジトリを再作成しても。
これをテストするために、 https ://github.com/cirosantilli/test-dangling というレポを作成し、次のことを行いました。
git init
git remote add origin git@github.com:cirosantilli/test-dangling.git
touch a
git add .
git commit -m 0
git push
touch b
git add .
git commit -m 1
git push
touch c
git rm b
git add .
git commit --amend --no-edit
git push -f
関連項目: GitHub からダングリング コミットを削除するには?
git filter-repo
が正式に推奨されるようになりましたgit filter-branch
これはgit filter-branch
、Git 2.5 自体のマンページに記載されています。
git フィルター リポジトリを使用すると、特定のファイルを次のように削除できます。 git/GitHub の履歴からフォルダーとその内容を削除します。
pip install git-filter-repo
git filter-repo --path path/to/remove1 --path path/to/remove2 --invert-paths
これにより、空のコミットが自動的に削除されます。
または、特定の文字列を次のように置き換えることもできます: Git 履歴全体で文字列を置き換えるには?
git filter-repo --replace-text <(echo 'my_password==>xxxxxxxx')
これがWindowsでの私の解決策です
git filter-branch --tree-filter "rm -f 'filedir/filename'" HEAD
git push --force
パスが正しいことを確認してください。そうしないと機能しません
役立つことを願っています
明確にするために:受け入れられた答えは正しいです。まず試してみてください。ただし、特に「致命的: 悪いリビジョン --prune-empty」などの不快なエラーが発生した場合や、リポジトリの履歴を本当に気にしない場合など、一部のユース ケースでは不必要に複雑になる可能性があります。
別の方法は次のとおりです。
もちろん、これにより、github リポジトリとローカル git リポジトリの両方から、すべてのコミット履歴ブランチと課題が削除されます。これが受け入れられない場合は、別のアプローチを使用する必要があります。
これを核オプションと呼んでください。
したがって、次のようになります。
git rm --cached /config/deploy.rb
echo /config/deploy.rb >> .gitignore
追跡されたファイルのキャッシュを git から削除し、そのファイルを
.gitignore
リストに追加します