453

Git プロジェクトを GitHub に置きたいのですが、機密データ (capistrano の /config/deploy.rb などのユーザー名とパスワード) を含む特定のファイルが含まれています。

これらのファイル名を.gitignoreに追加できることはわかっていますが、Git 内の履歴は削除されません。

また、/.git ディレクトリを削除してやり直したくありません。

Git 履歴から特定のファイルの痕跡をすべて削除する方法はありますか?

4

11 に答える 11

547

すべての実用的な目的のために、最初に心配する必要があるのは、パスワードの変更です! あなたの質問からは、あなたの 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

機密情報を含む変更ごとに。最終的にはブランチに戻り、新しい変更を安全にプッシュできます。

于 2009-05-16T16:04:11.857 に答える
114

パスワードを変更することは良い考えですが、リポジトリの履歴からパスワードを削除するプロセスについては、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 の作成者です。

于 2013-02-01T22:46:34.780 に答える
37

GitHub にプッシュした場合は、強制プッシュでは不十分です。リポジトリを削除するか、サポートに連絡してください

以下に説明するように、1 秒後に強制的に押しても十分ではありません。

有効な行動方針は次のとおりです。

  • パスワードのような変更可能な資格情報が漏洩したのは何ですか?

    • はい: パスワードをすぐに変更し、OAuth キーと API キーの使用を検討してください。

    • いいえ (裸の写真):

      • リポジトリ内のすべての問題が核攻撃されても気にしますか?

        • いいえ: リポジトリを削除します

        • はい:

          • サポート問い合わせ先
          • リークがあなたにとって非常に重要であり、リークの可能性を低くするためにリポジトリのダウンタイムを喜んで受け入れる場合は、GitHub サポートからの返信を待つ間、非公開にしてください。

次の理由により、1 秒後に押すだけでは十分ではありません。

ただし、強制的にプッシュするのではなく、リポジトリを削除すると、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')
于 2015-09-29T09:17:03.950 に答える
13

これがWindowsでの私の解決策です

git filter-branch --tree-filter "rm -f 'filedir/filename'" HEAD

git push --force

パスが正しいことを確認してください。そうしないと機能しません

役立つことを願っています

于 2016-12-02T19:19:31.663 に答える
8

明確にするために:受け入れられた答えは正しいです。まず試してみてください。ただし、特に「致命的: 悪いリビジョン --prune-empty」などの不快なエラーが発生した場合や、リポジトリの履歴を本当に気にしない場合など、一部のユース ケースでは不必要に複雑になる可能性があります。

別の方法は次のとおりです。

  1. プロジェクトのベースブランチへの cd
  2. 機密コード/ファイルを削除する
  3. rm -rf .git/ # コードからすべての git 情報を削除します
  4. github に移動し、リポジトリを削除します
  5. このガイドに従って、通常どおりコードを新しいリポジトリにプッシュします - https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/

もちろん、これにより、github リポジトリとローカル git リポジトリの両方から、すべてのコミット履歴ブランチと課題が削除されます。これが受け入れられない場合は、別のアプローチを使用する必要があります。

これを核オプションと呼んでください。

于 2015-01-25T23:38:51.210 に答える
2

したがって、次のようになります。

git rm --cached /config/deploy.rb
echo /config/deploy.rb >> .gitignore

追跡されたファイルのキャッシュを git から削除し、そのファイルを.gitignoreリストに追加します

于 2014-04-27T08:33:13.573 に答える