git filter-repo
ツールと BFG Repo-Cleaner によって、リポジトリの履歴が書き換えられます。これにより、変更した既存のコミットと依存するコミットの SHA が変更されます。 コミットの SHA を変更すると、リポジトリ内の開いている pull request に影響する場合があります。 リポジトリからファイルを削除する前に、開いているすべての pull request を結合または閉じることをお勧めします。
git rm
を使用して、最新のコミットからファイルを削除することができます。 最新のコミットで追加されたファイルを削除する方法については、「GitHub での大きいファイルについて」を参照してください。
警告: この記事では、機密データを含むコミットを、お使いの GitHub Enterprise Server インスタンス のリポジトリ内のブランチやタグからアクセスできないようにする方法について説明しています。 ただし、こうしたコミットも、リポジトリのクローンやフォークからは、GitHub Enterprise Server でキャッシュされているビューの SHA-1 ハッシュによって直接、また参照元の pull request によって、到達できる可能性があります。 リポジトリにある他のユーザーのクローンやフォークから機密データを削除することはできませんが、GitHub Enterprise Server 上のキャッシュされているビューや、pull request での機密データへの参照は、サイト管理者 に連絡して完全に削除することができます。
コミットを GitHub Enterprise Server にプッシュしたら、コミット内の機密データは侵害されたと見なすべきです。 パスワードをコミットした場合は、それを変更する必要があります。 キーをコミットした場合は、新たに生成してください。 侵害されたデータを削除しても、特にリポジトリの既存のクローンやフォークでの初期漏えいは解決されません。
機密データを含むコミットがリポジトリのフォークに存在する場合、フォーク所有者がフォークから機密データを削除するか、フォークを完全に削除しない限り、それに引き続きアクセスできます。 リポジトリのフォークの所有者と調整し、適切な措置を取るように依頼する必要があります。
リポジトリの履歴を書き換える場合は、これらの制限事項と課題を考慮して決めてください。
ファイルをリポジトリの履歴からパージする
git filter-repo
ツールまたは BFG Repo-Cleaner オープンソース ツールを使用し、リポジトリの履歴からファイルを消去します。
注: 機密データがバイナリ ファイルとして識別されるファイルに含まれる場合は、ファイルを変更してデータを削除または置換できないため、履歴からファイルを削除する必要があります。
BFG を使用する
BFG Repo-Cleaner は、オープンソース コミュニティによって構築および管理されているツールです。 不要なデータを削除するための、git filter-repo
より高速で簡単な代替手段が提供されます。
たとえば、機密データを含むファイルを削除して、最新のコミットをそのままにしておくには、次を実行します:
bfg --delete-files YOUR-FILE-WITH-SENSITIVE-DATA
リポジトリの履歴内の場所に関係なく、passwords.txt
に一覧表示されているすべてのテキストを置き換えるには、以下を実行します。
bfg --replace-text passwords.txt
機密データが削除されたら、変更を GitHub Enterprise Server に強制的にプッシュする必要があります。 強制的にプッシュすると、リポジトリの履歴が書き換えられます。これにより、コミットの履歴から機密データが削除されます。 プッシュを強制すると、他のユーザーが作業のベースにしているコミットが上書きされる可能性があります。
git push --force
完全な使用方法とダウンロード手順については、BFG Repo-Cleaner のドキュメントを参照してください。
git filter-repo を使用する
警告: 変更の一時退避後に git filter-repo
を実行すると、その他の stash コマンドを使用して変更を取得できなくなります。 git filter-repo
を実行する前に、行ったすべての変更の一時退避を解除することをお勧めします。 最後に一時退避した一連の変更の一時退避を解除するには、git stash show -p | git apply -R
を実行します。 詳細については、「Git ツール - 一時退避とクリーニング」を参照してください。
git filter-repo
の動作を説明するために、リポジトリの履歴から機密データを含むファイルを削除し、それを .gitignore
に追加して確実に、誤って再コミットされないようにする方法を示します。
-
git filter-repo ツールの最新リリースをインストールします。
git-filter-repo
は手動で、またはパッケージ マネージャーを使用してインストールすることができます。 たとえば、HomeBrew でツールをインストールするには、brew install
コマンドを使用します。brew install git-filter-repo
詳細については、
newren/git-filter-repo
リポジトリ内の INSTALL.md ファイルを参照してください。 -
履歴に機密データを含むリポジトリのローカル コピーがまだない場合は、ローカル コンピューターにリポジトリをクローンします。
$ git clone https://HOSTNAME/YOUR-USERNAME/YOUR-REPOSITORY > Initialized empty Git repository in /Users/YOUR-FILE-PATH/YOUR-REPOSITORY/.git/ > remote: Counting objects: 1301, done. > remote: Compressing objects: 100% (769/769), done. > remote: Total 1301 (delta 724), reused 910 (delta 522) > Receiving objects: 100% (1301/1301), 164.39 KiB, done. > Resolving deltas: 100% (724/724), done.
-
リポジトリの作業ディレクトリに移動します。
cd YOUR-REPOSITORY
-
次のコマンドを実行します。
PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
は、ファイル名だけでなく、削除するファイルへのパスに置き換えてください。 これらの引数では、次のことが行われます。-
すべてのブランチとタグの履歴全体を Git に強制的に処理させるが、チェックアウトはしない
-
指定されたファイルと、結果として生成された空のコミットをすべて削除する
-
リモート URL など、 .git/config ファイルに格納されている一部の構成を削除する。 後で復元するために、このファイルを事前にバックアップすることができます。
-
既存のタグを上書きする
$ git filter-repo --invert-paths --path PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA Parsed 197 commits New history written in 0.11 seconds; now repacking/cleaning... Repacking your repo and cleaning out old unneeded objects Enumerating objects: 210, done. Counting objects: 100% (210/210), done. Delta compression using up to 12 threads Compressing objects: 100% (127/127), done. Writing objects: 100% (210/210), done. Building bitmaps: 100% (48/48), done. Total 210 (delta 98), reused 144 (delta 75), pack-reused 0 Completely finished after 0.64 seconds.
注: (移動または名前が変更されたため) 他のパスに機密データが使用されたファイルが存在する場合は、これらのパスでもこのコマンドを実行する必要があります。
-
-
機密データを含むファイルを
.gitignore
に追加して確実に、誤って再度コミットしないようにします。$ echo "YOUR-FILE-WITH-SENSITIVE-DATA" >> .gitignore $ git add .gitignore $ git commit -m "Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore" > [main 051452f] Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore > 1 files changed, 1 insertions(+), 0 deletions(-)
-
リポジトリの履歴から必要なすべてを削除し、すべてのブランチがチェックアウトされていることを再確認します。
-
git filter-repo
ツールによって、構成済みのリモートが自動的に削除されます。git remote set-url
コマンドを使用すると、リモートが復元され、OWNER
とREPO
はリポジトリの詳細で置き換えられます。 詳しくは、「リモートリポジトリを管理する」を参照してください。git remote add origin https://github.com/OWNER/REPOSITORY.git
-
リポジトリの状態に問題がなく、リモートの設定が適切に完了したら、ローカルの変更を強制的にプッシュして、お使いの GitHub Enterprise Server インスタンス 上のリポジトリと、プッシュしたブランチをすべて上書きします。 コミットの履歴から機密データを削除するには、強制プッシュが必要です。
$ git push origin --force --all > Counting objects: 1074, done. > Delta compression using 2 threads. > Compressing objects: 100% (677/677), done. > Writing objects: 100% (1058/1058), 148.85 KiB, done. > Total 1058 (delta 590), reused 602 (delta 378) > To https://HOSTNAME/YOUR-USERNAME/YOUR-REPOSITORY.git > + 48dc599...051452f main -> main (forced update)
-
タグ付けされたリリースから機密ファイルを削除するには、Git タグに対して強制的にプッシュする必要もあります。
$ git push origin --force --tags > Counting objects: 321, done. > Delta compression using up to 8 threads. > Compressing objects: 100% (166/166), done. > Writing objects: 100% (321/321), 331.74 KiB | 0 bytes/s, done. > Total 321 (delta 124), reused 269 (delta 108) > To https://HOSTNAME/YOUR-USERNAME/YOUR-REPOSITORY.git > + 48dc599...051452f main -> main (forced update)
GitHub
からデータを完全に削除する
BFG ツールまたは git filter-repo
を使用して機密データを削除し、変更を GitHub Enterprise Server にプッシュした後、GitHub Enterprise Server からデータを完全に削除するには、さらにいくつかの手順を実行する必要があります。
-
サイト管理者 にお問い合わせいただき、GitHub Enterprise Server の pull request 内のキャッシュされたビューと機密データへの参照を削除するよう依頼してください。 リポジトリの名前と削除する必要があるコミットへのリンクの両方またはいずれかを指定してください。サイト管理者が到達できない Git オブジェクトを削除する方法の詳細については、「コマンド ライン ユーティリティ」を参照してください。
-
以前の (汚染された) リポジトリの履歴から、作成したブランチをマージ ではなく、リベースするようにコラボレーターに指示します。 マージコミットを 1 回でも行うと、パージで問題が発生したばかりの汚染された履歴の一部または全部が再導入されてしまいます。
-
一定の時間が経過し、BFG ツール/
git filter-repo
に意図しない副作用がないことを確信したら、次のコマンドを使用して、ローカル リポジトリ内のすべてのオブジェクトが強制的に逆参照され、ガベージ コレクトされるようにします (Git 1.8.5 以降を使用)。$ git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin $ git reflog expire --expire=now --all $ git gc --prune=now > Counting objects: 2437, done. > Delta compression using up to 4 threads. > Compressing objects: 100% (1378/1378), done. > Writing objects: 100% (2437/2437), done. > Total 2437 (delta 1461), reused 1802 (delta 1048)
注: フィルター処理した履歴を、新規または空のリポジトリにプッシュして、GitHub Enterprise Server から新しいクローンを作成しても、同じことができます。
将来にわたって誤ったコミットを回避する
共同作成者による誤ったコミットを防ぐことは、機密情報が公開されるのを防ぐのに役立ちます。 詳細については、「organization でのデータ 漏洩を防ぐためのベスト プラクティス」を参照してください。
コミット対象でないものがコミットされるのを回避するためのシンプルな方法がいくつかあります。
- GitHub Desktop や gitk などのビジュアル プログラムを使用して変更をコミットします。 ビジュアルプログラムは通常、各コミットでどのファイルが追加、削除、変更されるかを正確に把握しやすくするものです。
- コマンド ラインでの catch-all コマンド
git add .
とgit commit -a
を回避するには、代わりにgit add filename
とgit rm filename
を使用してファイルを個別にステージします。 git add --interactive
を使用して、各ファイル内の変更を個別に確認およびステージします。git diff --cached
を使用して、コミットのステージした変更を確認します。 これは、git commit
フラグを使用しない限り-a
で生成される正確な差分です。