GitHubのコミット履歴のコミッターを同一人物にすべて書き直す
普段から Git は使っていましたが、GitHub は最近利用を始めたばかりでした。
ローカル環境では特に気にする必要がないため何も設定していなかったのですが、そのまま作業を進めたことで、履歴上にメールアドレスが公開される状態になってしまっていました。
今回はこの問題を修正するために設定を見直したので、備忘録としてまとめておきます。
コミット履歴の状況
GitHubのコミット履歴を確認したところ、このような状態になっていました。
実際には本名ではなく普段プライベートで使用しているユーザー名でしたが、それでもセキュリティ的に少し不安を感じる状況でした。
VSCode上の GitGraph を使って初回コミットの履歴を確認してみたところはこちら。
……もろに個人のメールアドレスが残っていますね。
GitHubではコミット履歴が基本的に公開されているため、これだとメールアドレスが誰でも確認できる状態になってしまっています。
早急になおしてしまいましょう。
事前に必要なもの
- Python
- venvが利用可能になっていること
Pythonやvenvについては今回詳細に説明しません。
他の詳しい記事をご参考ください。
修正の準備
GitHubのダミーアドレス(noreplyメールアドレス)をコミット情報として使用する
GitHubではプライバシー保護を目的に使用できる「noreplyメールアドレス」が公式に提供されています。
GitHubに最近登録した人なら、こんな感じのメールアドレスが最初から付いてきます。
12345678+username@users.noreply.github.com
公式から提供されているわけですし、今回は遠慮なく使わせてもらいましょう。
ダミーアドレス(noreplyメールアドレス)を有効にする
GitHubにログインし、「Settings」→「Emails」を開くと、図のような設定があります。
「 Keep my email address private 」をONにすることで、「noreplyメールアドレス」がGitHubからわりあてられます。
文章中にあるメールアドレスがアカウントに紐づく「noreplyメールアドレス」です。
この画面を開けばいつでも確認できますが、いったんメモしておきましょう。
もう一つの設定、「 Block command line pushes that expose my email 」は、 自分の本物のメールアドレスを含むコミットのプッシュを拒否するか です。
ONにしておけば、自分のアカウントに紐づいているメールアドレスを使っている push を検出し、ブロックしてくれるようになります。
あくまで「自分のメールアドレス」だけです。
自分のプロファイルなので当然ではありますが、リポジトリに影響している設定ではありません。
これをONにしておけばそもそもこの記事もなかったのですが、怠慢が招いた不手際です。
泣きながらONにしました。
GitHubをブラウザ上での操作した場合のメールアドレスはどのメアドが使われる?
これは「 Keep my email address private 」のオン、オフに完全に依存しているらしいです。
私の場合はオンにはなっていたので、プルリクエストなどのWeb上での操作は「noreplyメールアドレス」、VSCodeなどクライアントからの操作は「個人メールアドレス」となっていました。
オフになっていればすべて「個人メールアドレス」になっていたかもしれないわけですね。
Gitローカル設定を変更する
「noreplyメールアドレス」が発行されたので、これを使う設定に変更します。
これはいつも通りのやり方で問題ありません。
私は標準の設定としてしまって問題ないので--grobal
をつけます。
git config --global user.name "ユーザ名"
git config --global user.email "12345678+yourusername@users.noreply.github.com"
実際に修正する
ここからは、修正が必要なプロジェクトごとに作業を行います。
プロジェクトに修正用のプラグインを導入する
今回のように、公開してしまったコミット履歴から個人情報を取り除くには、履歴そのものをさかのぼって改変する必要があります。
この作業を効率的に行うために導入したのが Gitが公式に推奨している履歴修正ツールgit-filter-repo
です。
とはいえあくまで私の思想ですがあまりGitの履歴そのものを修正する状況というのはあくまで非常時なものであり、常に削除できる状況にはしたくありませんでした。(便利ツールには頼りがちなので)
ですので今回はあくまで非常時の作業として、作業完了後に消せるように「venv」をつかって作業しようと思います。
もちろん「常に導入したいんだ!」という人はグローバルインストールしても問題ないかと思います。
導入手順
- 作業を行うプロジェクトでコンソールを開き、venvを有効にします。
python -m venv .venv
- venvをアクティベートして仮想環境を開きましょう
.\.venv\Scripts\activate
-
git-filter-repo
を仮想環境にインストールします
pip install git-filter-repo
これでプロジェクト内に作業をするための下準備が完了しました。
git-filter-repo
で履歴を修正する
まずはローカルリポジトリに対して作業を行います。
下記のコマンドを実行すると、コミット情報が修正されたあらたな履歴がプッシュされます。
git filter-repo --force --commit-callback "if True:
commit.author_name = b'{ユーザ名}';
commit.author_email = b'{noreplyメールアドレス}';
commit.committer_name = b'{ユーザ名}';
commit.committer_email = b'{noreplyメールアドレス}'"
{ユーザ名}
には任意のユーザ名、{noreplyメールアドレス}
には先ほど取得した「noreplyメールアドレス」で置き換えてください。
このコマンドを実行した後、新たに作られた履歴は根元から元の履歴と分かたれてしまうようなので、再度リモートリポジトリ(GitHub)のURLを設定してあげる必要があります。
私が使用しているリモートリポジトリの名前はoriginなので、originで設定します。
remote add origin {リモートリポジトリ(GitHub)のURL}
リモートリポジトリ(GitHub)のURLを再設定すると下のようなグラフになります。
ローカルリポジトリの履歴には、コミッターの情報が修正されたものが反映されています。(originはリモートリポジトリ(GitHub)なのでまだ反映されていません)
そこそこ履歴の詰まれたリポジトリだとグラフが2重化されるので、とても複雑怪奇になります。
パニックにならないように気をつけましょう。(私はなってreset
などで正そうとしてもう一回やる羽目になりました)
GitHubに修正した履歴を反映する
ここからはGitHubにローカルリポジトリの状態を反映します。
することは単純。全ブランチの強制プッシュです。
私が使用しているリモートリポジトリ(GitHub)の名前はoriginなので、originで強制プッシュします。
git push --all origin --force
git push origin --tags --force
作業をすれば先ほど2重化していたグラフも解消されます。
コマンドを実行してコミッターが1人しかいないのか確認しましょう。
git log --format='%aN <%aE>' | Sort-Object | Get-Unique
これはすべてのコミッターとメールアドレスの一覧を抽出するコマンドです。
結果が自分1人分だけしか返ってこなければ成功しています。
GitHub側の履歴も確認し、コミッターが修正されていれば完了です。
git-filter-repo
の削除
今回の作業で使用したgit-filter-repo
は、プロジェクトのルートに置かれた.venv
を削除すれば抹消されます。
これで心置きなく作業ができる状況となりました。よかった、よかった。
Discussion