提交代码之后屏幕突然弹出一段红色告警*** Please tell me who you are.配合前面那行Author identity unknown相信不少Git用户都撞见过。我第一次遇到这个报错时以为账号被服务器踢了又怀疑是网络断连折腾了快半小时才反应过来——Git根本不关心我从哪个服务器拉代码它只是因为这台机器上没有配置提交者身份老老实实地拒绝了这次提交。简单说这个报错的意思是Git不知道你叫什么名字、邮箱是什么所以无法在提交记录里标注作者。很多从SVN切换过来的同学尤其容易触发因为SVN是中央服务器统一鉴权而Git是分布式系统每次commit都要在本地写清楚“这是谁提交的”。本地没有身份信息Git宁可报错也不会替你瞎编一个名字塞进历史里。这篇文章把这个问题彻底讲透报错背后的配置层级、标准修复流程、那些“配了还报错”的隐藏原因、以及已经提交的错误作者信息如何补救。不管你是刚安装Git的新手还是在公司电脑上突然被这个报错拦住的老人都能在这里找到对应场景的解法。1. Author identity unknown不是网络问题是本地身份配置缺失1.1 完整报错长什么样我先还原一下实际报错的全貌。比如你刚完成修改执行git commit -m fix: 修复登录模块的SQL注入问题正常情况下Git会直接提交但在这台没有配置过身份的机器上你看到的是*** Please tell me who you are. Run git config --global user.email youexample.com git config --global user.name Your Name to set your accounts default identity. Omit --global to set the identity only in this repository. fatal: unable to auto-detect email address (got usernamehostname (none))注意最后一行fatal: unable to auto-detect email address。Git在找不到配置时会尝试用系统用户名和主机名去猜一个邮箱比如usernamehostname (none)猜不出来就直接卡住。很多人把注意力放在*** Please tell me who you are.上其实真正给线索的是最后一行。1.2 触发报错的几种常见起点我梳理了一下这个报错最常见的触发场景就这么几类刚装好Git从来没配置过user.name和user.email。新clone了一个仓库仓库里的.git/config没有继承全局身份。重装系统、换了新电脑旧的~/.gitconfig没迁移过来。使用sudo git commit读取的是root用户的配置而root没有配置身份。环境变量GIT_AUTHOR_EMAIL、GIT_COMMITTER_EMAIL被设置成了无效值导致原本好使的配置被覆盖。还有一类经常发生在公司电脑和个人电脑混用的场景你手头有多台机器有的机器配过有的机器没配过恰好在没配过的机器上提交就撞上了。1.3 Git提交记录里的“作者”到底从哪来很多人以为Git提交的作者是登录GitHub、Gitee的账号自动带上去的这是典型误区。Git的commit对象里有author和committer两个字段提交时会取配置文件里的user.name和user.email填入。如果没有配置commit命令直接报错退出。也就是说这个报错不涉及任何远端服务器即便你离线提交也一样会触发。我当时排查时先ping服务器、检查SSH key都是白费功夫。理解这一点能帮你省下大量排查时间。2. 动手修之前先搞清身份配置的三个层级2.1 system、global、local分别存在哪Git配置分三个层级分别对应不同的作用范围。我用一张表整理出来层级配置文件位置Windows示例配置文件位置macOS/Linux示例作用范围systemC:\Program Files\Git\etc\gitconfig/etc/gitconfig整台机器所有用户所有仓库global%USERPROFILE%\.gitconfig~/.gitconfig当前用户的所有仓库local.git/config仓库内部.git/config仓库内部仅当前仓库平时我们用的git config --global写入的是global层不加--global的git config写入的是local层。执行命令时Git会从这三个地方合并读取配置最终生效的值由优先级决定。2.2 用git config --list --show-origin定位当前生效值修复前先确认现状别上来就瞎配。最有效的命令是加--show-origin参数git config --list --show-origin它会列出所有配置项并标注每个值来自哪个文件。实际输出类似file:C:/Program Files/Git/etc/gitconfig core.symlinksfalse file:C:/Program Files/Git/etc/gitconfig core.autocrlftrue file:C:/Users/yourname/.gitconfig user.nameyourname file:C:/Users/yourname/.gitconfig user.emailyournameexample.com file:.git/config core.repositoryformatversion0如果列表里没有user.name和user.email那就是最普通的没配置问题。如果列表里能查到这两个字段但提交仍然报错说明问题没这么简单直接跳到后面第4章排查。2.3 优先级规则与“空值覆盖”陷阱三个层级的优先级是local global system。意思是同一个配置项仓库里的.git/config说了算其次是用户级配置最后才是机器级配置。这里有个非常隐蔽的坑local配置里如果存在user.name或user.email但值是空的比如clone某些模板仓库或者用IDE自动填充时留下的空字段它会覆盖掉global里配好的有效值。Git不会因为你global层配了身份就忽略local层的空值。我遇到过一次全局配置明明白白写着邮箱仓库里提交就是报错查了半天才发现是.git/config里的user.email是一个空字符串。3. 标准修复流程设置user.name和user.email3.1 一次性修复到当前用户最推荐的做法是配到global层这样当前用户的所有仓库都生效git config --global user.name Zhang San git config --global user.email zhangsanexample.com注意两点Windows的Git Bash里引号不能省否则带有逗号或特殊字符的值会被截断。邮箱不要写成昵称。很多平台GitHub、Gitee、GitLab靠邮箱把提交关联到账号邮箱写错了提交记录上不会显示你的头像也无法关联到你的账号。3.2 只改当前仓库的local配置如果你希望某个仓库用独立身份比如公司仓库用公司邮箱个人仓库用个人邮箱就不加--globalgit config user.name Zhang San git config user.email zhangsanexample.com这样写入的是当前仓库的.git/config只对这个仓库生效。道理和加不加--global完全对应加全局参数写用户级配置不加写仓库级配置。3.3 设置完怎么验证、怎么自查配置完成后先确认一下git config user.name git config user.email这两条命令会输出最终生效的值。如果输出正常说明配置已经就位再执行commit就不会报错了。如果输出空说明设置没写进去或者写到了另一个层级的文件里。还有一个排查命令值得记git config --get user.email--get和直接git config user.email的区别在于前者在读取到多个值时能更精准地显示命中项在某些场景下更容易暴露重复配置。我在排错时一般先用--show-origin看来源再用--get确认最终值。4. 配置了还是报错这五个隐藏原因最容易被忽略4.1 仓库本地配置存在空值前面已经提过.git/config里的空值是最大的坑。排查方法很简单git config --local --list或者直接打开.git/configcat .git/config如果看到类似email 这样的空字段把它删掉或修正即可git config --local --unset user.email然后重新设置正确的值。4.2 环境变量GIT_AUTHOR_*在悄悄覆盖Git允许通过环境变量临时指定提交作者官方定义的变量包括GIT_AUTHOR_NAME、GIT_AUTHOR_EMAIL、GIT_COMMITTER_NAME、GIT_COMMITTER_EMAIL。它们的优先级高于配置文件一旦被设置成错误值配置文件再对也没用。检查方法env | grep GIT_Windows PowerShell下用dir env:GIT_*如果发现有异常变量直接清掉unset GIT_AUTHOR_EMAIL unset GIT_COMMITTER_EMAIL这种坑特别容易出现在使用了某些自动化脚本、CI工具或者终端代理的环境里。我见过有人配置了全局身份后依然报错最后发现是安装某个Docker相关工具时往.bashrc里写了一个评估用的GIT_AUTHOR_EMAIL变量一直覆盖到现在。4.3 用sudo执行commit读错配置如果你在Linux或macOS上习惯加sudo执行命令那Git读取的是/root/.gitconfig和你自己用户下的配置不是一回事。可以先确认当前用户whoami如果显示root而配置里没有身份信息要么用root身份配置一次sudo git config --global user.name Zhang San sudo git config --global user.email zhangsanexample.com要么尽量不要用sudo执行Git命令避免权限和配置混乱。4.4 引号、换行、编辑器编码把配置内容弄脏了有的人用git config --global --edit打开编辑器直接改配置。如果在编辑过程中不小心把邮箱后面加了个空格、换行或者Windows记事本把UTF-8文件存成了带BOM的格式Git读取配置时可能解析出意外结果。遇到这种情况最快的方式是打开配置文件人工检查Windows用户notepad %USERPROFILE%\.gitconfigmacOS/Linux用户cat ~/.gitconfig重点检查[user]段落的格式标准写法是[user] name Zhang San email zhangsanexample.com如果你的配置里出现email zhangsanexample.com末尾多了空格或者值被折成多行都会导致解析异常。4.5 把SSH key和提交者身份混为一谈还有一个认知层面的高发误区。很多人配了SSH key机器也能免密拉代码就以为提交身份也没问题。实际上SSH key负责的是传输通道的认证解决的是“这台机器能不能访问远端仓库”的问题而user.name和user.email解决的是“提交记录上写谁的名字”的问题。两者完全独立。所以你会看到这样的现象SSH clone正常、pull正常、push正常但commit就是报Author identity unknown。原因就是机器和服务器之间的通道没问题但Git还是不知道本地提交者是谁。5. 已经产生错误提交怎么办有时候报错并不发生在第一次提交而是你之前已经用错误身份提交了一部分。等配置好身份后发现历史里一堆“匿名者”提交记录或者作者信息全是错的这时候就要分情况处理。5.1 push之前用amend修复如果错误提交还没有push到远端修起来非常轻松git commit --amend --reset-author --no-edit解释一下三个参数--amend修改最近一次提交。--reset-author把作者信息重置为当前配置的身份。--no-edit不修改提交信息。执行完后提交作者就会变成你配置好的身份。注意这个命令只对最近一次提交生效如果前面还有多笔错误提交需要用后面说的方法。5.2 已push的分支如何修正已经push到远端的分支修改提交历史会涉及重写必须谨慎。如果分支只有你一个人在用可以amend之后强制推送git push --force-with-lease这里推荐--force-with-lease而不是--force因为它会先检查远端是否有别人新提交的代码避免覆盖掉别人的工作。算是我踩过坑后养成的习惯凡是强制推送一律用--force-with-lease。如果错误提交不止一条可以用rebase配合amend批量处理git rebase -i HEAD~5在打开的交互界面里把需要修改作者的提交标记为edit然后在每个暂停点执行git commit --amend --reset-author --no-edit git rebase --continue一套流程走完所有涉及的提交作者都会被修正。5.3 批量重写历史提交的工具如果整条分支的作者信息全部错误且确认可以安全重写用git filter-branch可以一次性搞定。示例git filter-branch --env-filter if [ $GIT_AUTHOR_EMAIL wrongexample.com ]; then export GIT_AUTHOR_NAMECorrect Name export GIT_AUTHOR_EMAILcorrectexample.com fi -- --all这段脚本会遍历所有commit凡是作者邮箱等于wrongexample.com的提交都改成新的名称和邮箱。注意重写历史会改变commit的哈希值多人协作的分支不要随便用否则所有人的本地副本都会和远端“分手”。6. 长期使用一套配置方案解决多身份混用配置完身份只是解决了眼前的问题。如果你的工作环境同时有公司GitLab、GitHub、Gitee或者公司邮箱和个人邮箱需要严格分开一套动态身份切换方案能让后面省心很多。6.1 includeIf按目录分流Git 2.13开始支持includeIf配置。思路是把不同身份写进不同的配置文件然后按仓库所在目录自动加载。举个例子你约定公司项目统一放在~/work个人项目放在~/personal。先在~/.gitconfig主文件里写入[includeIf gitdir:~/work/] path ~/.gitconfig-work [includeIf gitdir:~/personal/] path ~/.gitconfig-personal然后分别建两个文件。~/.gitconfig-work[user] name Zhang San email zhangsancompany.com~/.gitconfig-personal[user] name Zhang San email zhangsangmail.com这样放在~/work目录下的仓库自动用公司邮箱提交放在~/personal下的仓库自动用个人邮箱提交不用再手动切来切去。6.2 Windows和macOS的路径写法差异gitdir:后面的路径写法和平台关系很大。macOS/Linux直接写~/work/没问题Windows要注意用正斜杠[includeIf gitdir:C:/work/] path ~/.gitconfig-work我见过一个朋友照抄网上的写法gitdir:里写的是C:\work\反斜杠被当成转义字符解析includeIf一直没生效。改成正斜杠后立刻好了。还有一个细节gitdir:~/work/末尾的斜杠表示匹配这个目录以及它下面的所有子目录。如果你只关心这一个仓库目录本身可以去掉末尾斜杠写gitdir:~/work。按实际需要来就行。6.3 我的个人配置习惯分享一套我目前在生产环境使用的方案供参考新机器装好Git后第一件事先配一套兜底global身份保证任何时候提交都不会被拦。公司项目统一放在D:/work个人项目放在D:/personal通过includeIf区分。所有远端平台的账号邮箱一定和本地user.email保持一致这样提交记录才能正确关联到账号。尽量少用git config --system改动系统级配置会影响机器上所有用户容易给同事挖坑。这套方案我用了快三年除了换新电脑时忘了迁移.gitconfig文件浪费了一点时间其他时候基本没再碰过Author identity unknown这个报错。最后再分享一个小技巧每次配置完身份想确认万无一失可以直接敲git config --global --list看看user段的内容。如果实在不放心就在某个测试仓库里git commit --allow-empty -m test提交一次一秒就能验证整个链路是否正常。这个报错本身不复杂绝大多数情况下就是配置缺失或配置层级混乱顺着配置来源一层层查总能找到问题。