我先把这条报错放在前面,方便直接搜索到的人立刻对上号:
code复制remote: Push will publish a hidden email.
remote: Make email public or abandon related commits.
这个报错在 Gitee 上很常见,尤其是新注册账号、或者用 QQ 邮箱注册后自己又去开了“隐藏邮箱”开关的人。第一次 push 时看到这个英文提示,很多人会懵:我明明在 Gitee 上能看到仓库,本地 commit 也成功了,为什么偏偏 push 不上去?到底是谁拦了我的代码?
这篇文章会直接告诉你三件事:第一,Gitee 为什么会在 push 环节拦你;第二,怎么用最简单的方式放行;第三,如果你既不想公开邮箱、又想把代码推上去,应该怎么处理相关的 commit。整个排查和操作过程我会按实际踩坑的顺序写,涉及的 Git 命令都是可以直接复制执行的。
1. 这个报错到底是谁抛出来的:本地 Git 和 Gitee 的隐私校验机制
先理清一个概念:这条报错不是本地 Git 报的。本地 Git 在执行 git push 时,只会把对象打包上传到远端,收到远端 HTTP/SSH 服务的响应后,再把响应内容打印在终端里。所以你看那两行 remote: ... 开头的文本,其实是 Gitee 服务器端返回给你的业务提示,不是 Git 协议本身的错误。
Gitee 在接收 push 时,会扫描这次推送涉及的所有 commit 的 author 邮箱 和 committer 邮箱。它会拿这些邮箱去和你的账号设置做比对。如果在 Gitee 账号的邮箱设置里,你把某个邮箱设为“隐藏”状态,而提交里的邮箱又正好命中这个隐藏邮箱,gitee 就会认为:“这个用户把邮箱藏起来了,但这个 commit 又要公开显示,这样会泄露隐私,或者会产生无法对应账号的提交记录。”于是干脆拒绝整个 push。
这里面有一个容易误解的地方:很多人以为“隐藏邮箱”只是让第三方看不到,Gitee 服务器自己永远是能看到的。但问题恰恰在于——服务器能看到,服务器也知道那是你,服务器还知道你不希望公开。当一个 commit 的作者邮箱被标记为隐藏时,Gitee 的展示系统会给出一个替代邮箱占位符,比如 username@webmaster.gitee.com 之类的。可仓库的提交历史里真实邮箱已经被写进 Git 对象了,这是不可能动态改掉的。所以 Gitee 只能通过“拒绝推送”来逼你做一个选择:要么把邮箱公开放行,要么把历史里用了隐藏邮箱的 commit 处理掉。
我在本地 Git 配的 user.email 用的是注册 Gitee 的 QQ 邮箱,注册后又在设置里开了“邮箱隐藏”,然后造了个新仓库第一次 commit、push,当场复现了这条报错。终端完整输出大致是这样的:
bash复制$ git push -u origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 222 bytes | 222.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), reused 0 (delta 0)
remote: Push will publish a hidden email.
remote: Make email public or abandon related commits.
remote:
remote: The following commits have a hidden email:
remote: d2f9a1c init
remote:
To gitee.com:xxx/test-private-email.git
! [remote rejected] master -> master (push declined due to email privacy)
error: failed to push some refs to 'gitee.com:
