delhi09の勉強日記

技術トピック専用のブログです。自分用のメモ書きの投稿が多いです。あくまで「勉強日記」なので記事の内容は鵜呑みにしないでください。

Git/GitHubのメールアドレス周りについて調べた

概要

Gitを使い始めるときに、最初に`git config'コマンドで以下のようにユーザー名とメールアドレスを登録する事になると思う。

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

git-scm.com

ここで登録したメールアドレスが何に使われているのかとかをちゃんと理解していなかったので調べてみることにした。

ピュアGitの場合

そもそもなぜGitにメールアドレスの設定が必要なのか

GitHubやGitLabは「Gitを扱うためのWEBアプリケーション」なので、メールアドレスが必要なのは分かる。

しかし、ピュアなGitに関しては、メールアドレスを使って認証している訳でもないし、なぜメールアドレスの設定が必要なのかというのは、そもそも疑問だった。(開発チーム内で誰がコミットしたかを一意に識別したいだけなら、ユーザー名だけ必須で設定すればよいのでは?と思っていた。)

これに関しては、以下のQuoraのQAが考える上で参考にはなったが、根拠となるような一次情報には辿り着けなかった。
www.quora.com


従って、あくまで個人的な推測だが

  • ユーザー名だけだと複数のPJに関わったときに衝突する可能性が高い。
  • 個人が既に持っているもので、一意識別子に使えそうなものというと、メールアドレスか携帯の電話番号くらいしかない。(その2択ならメアドの方がベター)
  • Gitが開発された当時は、Slackとかメールよりも便利なコミュニケーション手段はなかったはずなので、コミットの内容について問い合わせたいときに連絡先がすぐに分かった方がよい。

などの理由だったのかな?と思った。

メールアドレスが何に使われているか

git logで確認すると分かるが、設定したメールアドレスは以下のように、GitのコミットのAuthor情報として埋め込まれる事になる。

f:id:kamatimaru:20210327145731p:plain

従って、リポジトリをcloneすれば誰でもこのメールアドレスはみられるので、公開したくないメールアドレスはgitのconfigには設定するべきではない。

GitHubの場合

メールアドレスが何に使われているか

GitHubの場合は、上で説明したことに加えて、コミット情報に埋め込まれたメールアドレスと、GitHub上で認証済みのメールアドレスの照合が行われる。

GitHub上で認証していないメールアドレスがgitのconfigに設定されている状態でも、GitHub上のリポジトリにコミット&プッシュはできるが、GitHub上でコミットログをみたときに、コミットのAuthorとGitHubのアカウントが紐付いていない状態になる。

  • メールアドレスが未認証の状態

f:id:kamatimaru:20210327151928p:plain

  • メールアドレス認証後

f:id:kamatimaru:20210327151948p:plain

以下の公式ドキュメントに記載の通り、メールアドレスを追加でGitHubに認証すれば、後からでもAuthorとGitHubのアカウントを紐づけることができる。
docs.github.com

「Keep my email address private(メールアドレスをプライベートに保つ)」設定について

docs.github.com

上記の公式ドキュメントに記載の通り、GitHubの画面上からSettings → Emailで、「Keep my email address private」という項目にチェックを入れると

  • GitHub上でマージしたとき
  • GitHub上でファイルを編集&コミットしたとき

などのコミット時に使用されるAuthorのメールアドレスは、GitHubに登録したメールアドレスの代わりに、GitHubがユーザーごとに提供しているxxx@users.noreply.github.comというメールアドレスが使用される。(このメアドについては後述する。)

例えば、この設定を有効にした状態でPull Requestをマージすると、コミットログは以下のようになる。
f:id:kamatimaru:20210327154721p:plain

ただ、この設定の意味はあくまでこれだけであって、他のユーザーであっても、リポジトリをcloneしてコミットログを確認すれば、普通にローカルでのコミットのAuthorのメールアドレスは閲覧可能である。

従って、「公開したくないメールアドレスはgitのconfigには設定するべきではない」という原則は変わらない。

GitHubが提供してくれているメールアドレスについて

説明が前後したが、以下のドキュメントに記載の通り、GitHubはユーザーごとにgithub.comドメインのメールアドレスを提供してくれている。

注釈: GitHubアカウントを2017年7月18日以降に作成した場合、GitHubが提供するno-replyメールアドレスは7桁のID番号とユーザ名をID+username@users.noreply.github.comという形式にしたものになります。

docs.github.com

最初にこの説明をみたときは「7桁のID番号って何だろう?」と思ったが、先に説明した「Keep my email addresses private」の項目の説明文から自分に付与されているメールアドレスが分かる。

We’ll remove your public profile email and use 63476957+delhi09@users.noreply.github.com when 〜

また、コミットのAuthor情報に埋め込まれているメールアドレスがこのメアドであっても、GitHubはアカウント情報と紐付けてくれるので、公開してもよいメールアドレスがないという場合は、このメアドをgitのconfigに設定してもよい。
(ただ、あくまでGitHubの独自仕様なので、GitLabやBitbucketも併用している場合は、globalに設定するのは微妙かもしれない)

$ git config --global user.email 63476957+delhi09@users.noreply.github.com

※ 以下エビデンス
f:id:kamatimaru:20210327162352p:plain

f:id:kamatimaru:20210327162444p:plain

既存のコミットのメールアドレスを後から修正したいとき

既にコミットしまったコミットログのメールアドレスを後から修正したいという場合もあるかもしれない。

その場合は、filter-branchというオプションがあることを知った。

【重要】ただし、コミットログのハッシュ値が全て変わってしまうので、実行してよいかは各自の置かれた状況に応じて判断が必要である。

Gitの公式ドキュメントにも「メールアドレスの一括変更」というピンポイントな具体例とともに記載されているので、実行する場合は基本このドキュメントの通りにやればよい。

$ git filter-branch --commit-filter '
        if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
        then
                GIT_AUTHOR_NAME="Scott Chacon";
                GIT_AUTHOR_EMAIL="schacon@example.com";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

git-scm.com

本当に個人用のリポジトリでコミッターが自分しかないなら、上記公式ドキュメントに記載のコードのif文の部分も不要で、以下のような1行を実行すればよい。

$ git filter-branch --commit-filter 'GIT_AUTHOR_NAME="Scott Chacon"; GIT_AUTHOR_EMAIL="schacon@example.com"; git commit-tree "$@";' HEAD

実行すると、コミットログの量にもよると思うが、少し実行時間がかかる。

正常終了したら、git logでコミットのAuthor情報が書き変わっていることを確認する。

最後に、コミットIDも変わっているので、git push -fで強制プッシュすればOK。

参考文献

以下の記事を参考にさせて頂きました。

taikii.net
qiita.com
ryoichi0102.hatenablog.com