Web便利ツール集

Gitのコミットでメールアドレスが公開される?noreply設定と過去履歴の直し方

GitGitHubメールアドレス個人情報noreplyコミット履歴プライバシー

個人開発のコードをGitHubに公開したあとで、「コミットに自分のメールアドレスと本名が入っているのでは」と気づくことがあります。設定を直せば済むと思いがちですが、設定を変えても、すでに作ったコミットは書き換わりません。 この記事では、なぜ見えるのか、今後を防ぐ設定、過去の履歴の直し方、そして直したつもりでも残る場所を、手元の Git で実測した結果とあわせてまとめます。

結論:設定で「今後」を止め、「過去」は別作業で直す

先に全体像です。

やりたいこと方法注意点
今後のコミットに実アドレスを入れないgit config を noreply アドレスに変える過去のコミットは変わらない
誤って実アドレスで push するのを防ぐGitHub側の「メールを非公開」「コマンドラインのpushをブロック」設定設定画面の文言は変わることがある
直近1件だけ直すgit commit --amend --reset-author1件しか直らない
履歴全体を直すrebase・filter-branch・git filter-repo強制pushが必要。共同作業者に影響する
直したあとの取りこぼしを防ぐタグ・メッセージ・退避用の参照を確認する本記事の後半で説明

履歴の書き換えは、公開済みリポジトリでは影響が大きい作業です。書き換える前に、本当に書き換える価値があるかを判断することも大切なので、その基準も後半に書きました。

なぜコミットからメールアドレスが見えるのか

Git のコミットには、「誰が書いたか(author)」と「誰がコミットしたか(committer)」が、名前とメールアドレスのセットでコミット自体に記録されます。リポジトリを clone した人なら誰でも、次のコマンドで読めます。

git log --format='%h %an <%ae> | %cn <%ce>'

手元で作った検証用のリポジトリでは、次のように表示されました。

b746bbd Taro Yamada <[email protected]> | Taro Yamada <[email protected]>
21db54d Taro Yamada <[email protected]> | Taro Yamada <[email protected]>

%ae が author のメールアドレス、%ce が committer のメールアドレスです。GitHub のWeb画面でコミットを開いても、パッチ形式で出力しても、同じ情報が含まれます。パッチ形式(git format-patch)の先頭行にも From: Taro Yamada <[email protected]> が入ることを確認しました。

つまり、見えているのは GitHub のアカウント設定ではなく、あなたの PC の git config に書いてあった値です。

手順1:今後のコミットを noreply アドレスにする

GitHub には、メールアドレスを公開せずにコミットを自分のアカウントに紐づけるための noreply 用アドレスがあります。形式は 数字+ユーザー名@users.noreply.github.com です。実際の値は、GitHub の設定画面(メール設定)に表示されるものを使ってください。この記事の例の 12345+taro@... は形式を示すための仮の値です。

設定画面の項目名や配置は変更されることがあります。本記事は GitHub の画面を実際に操作して確認したものではなく、公式ドキュメントと公開されている解説を確認したうえでの一般的な説明です。最新の手順は公式ドキュメントで確認してください。

Git 側の設定

git config --global user.name "Taro Yamada"
git config --global user.email "[email protected]"

--global を付けると、その PC のすべてのリポジトリに効きます。特定のリポジトリだけ変えたい場合は、リポジトリの中で --global を外して実行します。

GitHub 側の設定

GitHub のメール設定には、実アドレスを非公開にする項目と、実アドレスを含むコミットのコマンドラインからの push を拒否する項目があります。後者を有効にすると、実アドレスのコミットを push したときに、GH007 というエラーで拒否されたという報告が複数あります。

誤って実アドレスで公開してしまう事故を防ぐ保険になります。ただし、この設定は「これから push するもの」に対する防御です。すでに公開済みの履歴を消す機能ではありません。

仕事用と個人用を使い分けている場合

会社用と個人用でメールアドレスを分けているなら、フォルダ単位で自動的に切り替える方法があります。~/.gitconfig に次のように書きます。

[user]
	name = Me
	email = [email protected]
[includeIf "gitdir:~/work/"]
	path = ~/.gitconfig-work

~/.gitconfig-work に email = [email protected] と書いておくと、~/work/ 配下のリポジトリだけ会社用のアドレスになります。実測では、~/work/p 配下で git config user.email が [email protected]、~/priv/p 配下では [email protected] になりました。設定ミスを減らす方法として有効です。

手順2:過去の履歴にどのアドレスが残っているか確認する

設定を直したら、すでに履歴にどのアドレスが入っているかを数えます。

git log --all --format='%ae%n%ce' | sort | uniq -c

author と committer の両方を、全ブランチ・全タグから集計するコマンドです。実アドレスが1つでも出てきたら、そのコミットは過去の分として残っています。

実測では、設定を noreply に変えたあとのコミットだけが noreply になり、それ以前の2コミットは実アドレスのままでした。

dde5d84 [email protected] | [email protected] third
b746bbd [email protected] | [email protected] second
21db54d [email protected] | [email protected] first

「設定を変えたから大丈夫」ではなく、上のコマンドで確認するまで安心しないのが安全です。

手順3:過去の履歴を書き換える3つの方法

方法A:直近の1コミットだけ直す

git commit --amend -C HEAD --reset-author

--reset-author は、author を今の設定に置き換えます。実測で、直近の1件だけ noreply に変わり、残りは変わらないことを確認しました。直した1件のハッシュも変わります。

方法B:rebase で全コミットを順に直す

最初のコミットから順に、全部を作り直す方法です。

git rebase --root --exec "git commit --amend -C HEAD --reset-author -q"

手元の3コミットのリポジトリでは、3件とも noreply に変わりました。シンプルですが、マージコミットを含む履歴で正しく動くかは、今回は検証していません。 分岐とマージが多いリポジトリには向かないと考えられます。

方法C:filter-branch または git filter-repo

全ブランチ・全タグをまとめて書き換える方法です。Git 標準の git filter-branch で、メールアドレスを置き換える例です。

git filter-branch -f --env-filter '
export GIT_AUTHOR_EMAIL="[email protected]"
export GIT_COMMITTER_EMAIL="[email protected]"
' --tag-name-filter cat -- --all

実測では、全コミットのアドレスが置き換わりました。ただしこの書き方は全員のアドレスを一律に置き換えます。 複数人が関わるリポジトリで、特定のアドレスだけを置き換えたい場合は、条件分岐を入れる必要があります(この条件分岐は今回検証していません)。

git filter-branch は、Git の公式マニュアルでも使用が推奨されておらず、別ツールの git filter-repo が推奨されています。git filter-repo では、--mailmap に対応表を渡して名前・メールアドレスを置き換える方法が紹介されています。ただし、私の環境には git filter-repo が入っていないため、この方法は実行して確認していません。 使う場合は、先にバックアップのクローンで試してください。

他所ではあまり書かれていない落とし穴:直したのに残る5か所

ここが本記事で最も伝えたい部分です。コミットの author と committer を書き換えても、実アドレスが別の場所に残ることを実測で確認しました。

1. 注釈付きタグの tagger

git tag -a で作った注釈付きタグには、コミットとは別に tagger(タグを付けた人)のメールアドレスが入ります。

git cat-file -p v1
object b746bbde11fbc5551008317bc79e7e71ff8b7fa9
type commit
tag v1
tagger Taro Yamada <[email protected]> 1793264513 +0900

rebase で全コミットを直したあとも、タグは書き換え前のコミットを指したままで、tagger も実アドレスのままでした。さらに、filter-branch に --tag-name-filter cat を付けてタグを作り直した場合でも、tagger のアドレスは実アドレスのままでした。

実測で有効だったのは、タグを作り直す方法です。

git tag -f -a v1 -m "release v1" <書き換え後のコミット>

この方法で、tagger が noreply アドレスに変わりました。タグを公開している場合は、リモート側のタグも更新する必要があります。

2. コミットメッセージ内の Co-authored-by

共同作業者を示す Co-authored-by: の行は、コミットメッセージの本文です。author や committer を直しても、本文は書き換わりません。実測でも、rebase のあとに次の行がそのまま残っていました。

second

Co-authored-by: Hanako <[email protected]>

Signed-off-by: なども同じ扱いと考えられます。メッセージ本文のアドレスは、メッセージ自体を書き換える必要があります。しかも、他人のアドレスを勝手に書き換えるのは避けるべきです。本人の了承を得てください。

3. refs/original に退避された古いコミット

git filter-branch は、書き換え前の状態を refs/original/ に退避します。実測でも、書き換え後に git for-each-ref で refs/original/refs/tags/v1 が残っていました。

書き換え後に git log --all を実行すると、この退避されたコミットも集計に含まれます。実際に、全体を書き換えたあとでも、実アドレスのコミットが2件、--all の集計に出ました。直したつもりでも、古いコミットが手元に残っている状態です。

退避用の参照を削除し、不要になったオブジェクトを掃除する手順は次のとおりです。

git for-each-ref --format='%(refname)' refs/original | while read r; do git update-ref -d $r; done
git reflog expire --expire=now --all
git gc --prune=now

実測では、削除前は古いコミットを git cat-file -t で参照できましたが、実行後は could not get object info になり、参照できなくなりました。この掃除は元に戻せません。 必ずバックアップを取ってから実行してください。

4. .mailmap は「見え方」しか変えない

リポジトリに .mailmap を置くと、git log などの表示上、アドレスを別のものに読み替えられます。実測では、%ae(実際の値)はそのままで、%aE(mailmap を適用した値)だけが変わりました。

[email protected] | [email protected]

つまり .mailmap は履歴を書き換えるものではなく、表示を変えるだけです。実アドレスを隠す目的には使えません。検索でも、GitHub 上では mailmap が表示される内容だけを変え、コミットの作成者そのものは変えないという指摘が確認できました。

5. 強制 push してもフォーク・クローン・キャッシュには残る

ここは実測できない部分です。公開済みのリポジトリで履歴を書き換えて強制 push しても、すでに clone された手元のコピーや、フォークには古い履歴が残ります。 GitHub の公式ドキュメントでは、機密データの削除の文脈で、履歴を書き換えて強制 push するだけでは、機密データを含むコミットがほかの場所から参照できる場合があると説明されています。メールアドレスも同じ構造だと考えられます。

書き換えるべきか:判断の目安

履歴の書き換えは、コストの高い作業です。次の表で判断してください。

状況判断の目安
まだ誰にも公開しておらず、ローカルだけ今すぐ直してよい。影響が小さい
公開して間もない・共同作業者がいない書き換えを検討してよい。バックアップを取ってから
公開して長い・フォークやスターが多い書き換えても、すでに複製された分は消せない。効果は限定的と考えられる
共同作業者がいる強制 push で全員の履歴が食い違う。全員が再 clone する調整が必要
実アドレスへの迷惑メールが気になる履歴の書き換えより、そのアドレス自体の見直しを優先

公開済みの履歴から実アドレスがすでに収集されている可能性は否定できません。実際に収集されたかどうかは外から確認できません(推測です)。そのため、書き換えに加えて、次の対策も検討する価値があります。

  • 迷惑メールが増えたら、そのアドレスでの受信を絞る、または別のアドレスに切り替える
  • 重要なアカウントのメールアドレスと、コミット用のアドレスを分ける
  • 今後のコミットは必ず noreply アドレスにして、新たな露出を止める

写真に位置情報が残る問題と構造が似ています。作った時点で埋め込まれ、あとから設定を変えても消えない、という点です。写真の場合は 写真のExif位置情報を削除する方法 で整理しています。

実測した環境と、確認できていないこと

誤解を防ぐため、確認の範囲を明記します。

  • 確認した環境: Windows 上の Git 2.27.0 で、一時ディレクトリに作った検証用リポジトリ(3コミット・注釈付きタグ1つ)
  • 確認したこと: 設定変更が過去のコミットに影響しないこと、--amend・rebase・filter-branch の結果、タグ・Co-authored-by・refs/original に残ること、.mailmap が表示だけを変えること、includeIf の切り替え
  • 確認していないこと: GitHub の画面操作、GH007 エラーの再現、git filter-repo の実行、マージコミットを含む履歴での rebase、複数人のリポジトリでの条件付き置き換え、他のバージョンの Git での挙動

GitHub 側の設定項目や仕様は変わる可能性があるため、実行前に公式ドキュメントを確認してください。また、この記事は一般的な整理であり、個別の事案について結論を示すものではありません。個人情報の漏えいが業務や法的な問題に関わる場合は、所属先のセキュリティ担当や専門家に相談してください。

まとめ

  1. コミットのメールアドレスは PC の git config の値がコミットに焼き込まれる。GitHub の設定では後から直らない
  2. 今後のコミットは noreply アドレスに設定し、GitHub 側の「実アドレスを含む push をブロック」も有効にしておく
  3. 過去の履歴は git log --all --format='%ae%n%ce' | sort | uniq -c で必ず集計して確認する
  4. 書き換えても タグの tagger、Co-authored-by、refs/original、.mailmap、フォーク・クローンには残りうる。作業後に再集計する
  5. 公開済みの履歴は完全には消せない。強制 push のコストと効果を比べて判断し、実アドレス自体の見直しも並行する

アカウントまわりの対策としては、安全なパスワードの作り方 もあわせて確認しておくと安心です。

関連記事