git filter-repo
ツールと BFG Repo-Cleaner によって、リポジトリの履歴が書き換えられます。これにより、変更した既存のコミットと依存するコミットの SHA が変更されます。 コミットの SHA を変更すると、リポジトリ内の開いている pull request に影響する� �合があります。 リポジトリからファイルを削除する前に、開いているすべての pull request を結合または閉じることをお勧めします。
git rm
を使用して、最新のコミットからファイルを削除することができます。 最新のコミットで追� されたファイルを削除する方法については、「GitHub の大きなファイルについて」を参照してく� さい。
警告: この記事では、機密データを含むコミットに、 のリポジトリ内のブランチまたはタグから到達できないようにする方法について説明しています。 た� し、こうしたコミットも、リポジトリのクローンやフォークからは、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-branch
より高速で簡単な代替手段が提供されます。
たとえば、機密データを含むファイルを削除して、最新のコミットをそのままにしておくには、次を実行します:
$ 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://ホスト名/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 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://ホスト名/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://ホスト名/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 上で、キャッシュされているビューと、プルリクエストでの機密データへの参照を削除するよう依� �します。 リポジトリの名前と削除する必要があるコミットへのリンクの両方またはいずれかを指定してく� さい。サイト管理者が到達できない 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 から新しいクローンを作成しても、同じことができます。
将来にわたって誤ったコミットを回避する
コミット対象でないものがコミットされるのを回避するためのシンプルな方法がいくつかあります。
- 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
で生成される正確な差分です。