为啥Github允许冒充别人的身份Commit
git本身允许这么做的。
假如我们有一个commit 8980661603a69a7f3e638b3e47a33c27a1fb3837,用命令git cat-file -p 8980661603a69a7f3e638b3e47a33c27a1fb3837可以看到这个commit的内容:tree bb2349b57089536ac5013480d47a092d07fa602dparent db6702e9efd7bd42fa4a8bde782fa178ccb6f998author Elpie Kay \u0026lt;elpiekay@kk.com\u0026gt; 1469971966 +0800committer Elpie Kay \u0026lt;elpiekay@kk.com\u0026gt; 1469971966 +0800fix a bugrootcause:xxxsolution:yyy其中的author和committer,包含了名字、邮箱和时间戳。一般情况下,第一次生成的commit,author和committer是同一个人。也是在一般情况下,如果另一个人用git cherry-pick, git rebase, git commit --amend, git filter-branch, git format-patch \u0026amp;\u0026amp; git am之类的git命令重写了这个commit,其实都是新生成了一个commit,那么新生成的那个commit的author还是原来的,但committer会变成执行这个操作的用户的名字和邮箱。可以简单地理解成author是第一作者,committer是生成commit的人,这2个角色可能是同一个人也可能是不同的人。
但是git是怎么知道用户的名字和邮箱的呢?是从gitconfig中读取到的。读的是user.name和user.email的值。假如这两个值都没设置的话会怎么样呢?你可以试下。
gitconfig是存储在文件里的,这些文件可以通过git config命令或者直接编辑来修改,那么也就意味着user.name和user.email是可以随意更改的。这样,就可以伪造别人的身份来生成commit了,commit里的author和committer的身份的可靠性为0。
但是通过改变gitconfig来伪造身份不是很灵活,git还提供了其它更灵活的方式来提供身份信息。首先还是通过gitconfig,但是不是通过更改config文件。gitconfig里的设置项都是键值对,git通过-c参数可以提供临时的config键值对,只对本次命令有效。譬如用新身份重写最后一个commit:git -c user.name="Linus Torvalds" -c user.email="233max@qq.com" commit --amend --no-edit这样会把最后一个commit的committer伪装成是Linus Torvalds。
其次是使用环境变量:GIT_AUTHOR_NAME="Linus Torvalds" GIT_AUTHOR_EMAIL="linus@qq.com" \\git commit --allow-empty -m "fake news"最后还有一个大杀器,git filter-branch。这个命令可以编程式地改写commit历史。这里只讲写怎么改写author和committer信息,需要用到它的--env-filter参数。以下命令会把最后2个commit的author和committer篡改掉。git filter-branch \\ --env-filter \u0026#39;GIT_AUTHOR_NAME="Linus Torvalds" \\ GIT_AUTHOR_EMAIL="Linus@qq.com" \\ GIT_COMMITTER_NAME="Linus Torvalds" \\ GIT_COMMITTER_EMAIL="Linus@qq.com"\u0026#39; \\ HEAD~2..Github作为一个代码托管网站,用户遍布全世界。用户在本地做好的commit再push上来,Github也不好校验每个commit的作者是不是真的某个人。Github我不清楚是不是有类似的校验功能,但是我知道的其它托管工具,譬如Gerrit是有设置项可以用来进行一定程度的校验的。Gerrit会比较推送时使用的账号和要推送审核的commit里的committer信息是否一致,还会利用在Gerrit上注册时绑定的邮箱来校验commit里的committer email是否一致。如果不一致的话,就拒绝推送。这样就限制了一个用户只能推送他自己的新提交,账号密码泄露了另当别论。当然,这也没法完全杜绝身份伪造的情况,毕竟author信息它是没法校验的。在实际使用场景中,我们可能会要推送第三方提供给我们的commit到Gerrit服务器上,不可能帮每个commit的committer在我们的Gerrit服务器上注册一个账号、绑定一个邮箱,所以Gerrit也提供了设定允许某个用户可以推送其他用户生成的commit。这个是作为Gerrit权限管理的一部分,就不展开讲了。不管怎样,托管网站来进行完全的校验是不合理的需求。
推荐阅读
- 为啥看到书柜上的藏书会有心旷神怡的感觉
- 为啥知乎上普便有一种【我在北上广深打工,所以拥有更好的视野】这样的错觉
- 为啥工商银行的用户体验如此之差
- 汽车|看了中消协4S店服务测评调查结果,终于知道法系车为啥卖不好了
- 你为啥从窝窝商城离职?
- 为啥5G和2.4G默认的BSSID是相同的
- 为啥电器实体店的价格比淘宝贵那么多
- 现在在线学习视频有很多了,为啥大部分人还是喜欢下载下来观看
- 为啥到现在你还没有女朋友 ?
- 天赐的声音|33岁张雨绮为啥总离婚?看过这些照片就明白了,都是性感惹得祸
