我最近开始研究一个使用GitHub进行源代码控制的项目。我已经习惯了SVN并且对它很满意,我是Git的新手,关于它的一些事情非常烦人。其中之一是我需要明确配置user.name
和user.email
参数(或者任何正确的术语,它似乎没有在文档中提及,像许多其他事情一样)。也许它有意义,因为我在本地提交时不需要提供凭据。但是当我推送我的更改并且只接受设置的user.name
值而不检查它是否与我的登录匹配时,它确实会询问我的凭据。然后GitHub以别人的名字显示我的更改,这非常令人困惑。
这背后有一些深刻的智慧,还是只是草率的代码?
答案 0 :(得分:3)
这既不是深刻的智慧也不是草率的代码。这只是distributed system的性质。
您的Git存储库是您的。你可以在所有方面控制它。您决定放入什么以及放下什么。您还可以决定是否以及何时对提交和/或标记进行数字签名(请参阅git tag --sign
和大量PGP文档)。
当然,你也可以控制转会点。具体来说,在某些时候,有人会给你一些提交和/或标签,以及随之而来的东西(树和blob),并要求你将它们放在你的存储库中。如果您要从中检索数据,则此操作为git fetch
;如果他们向您发送数据,则此操作为git push
。您可以在那时决定是接受他们还是拒绝他们。 Git通过“钩子”直接控制这个相当二元的操作。
em>接受他们但更改他们。人们甚至可以想象一个系统,在这个系统中,这个过程被正式化并在获取或推送会话期间直接允许:“我看到你正在向我提供这些提交和其他对象,但我不喜欢它们,我会修改它们。“
有一些很好的技术原因不这样做。特别是,Git对象的标识是其内容的加密散列,如果接收Git要调整或替换部分或全部内容,则必然会产生新的散列。散列函数被故意设计为“单向”,即,仅给出散列,很难产生产生该散列的内容。因此,为了使其工作得非常好,接收Git不仅要对发送Git说:“我真的不喜欢它,但是如果你把它改成我将把它带走 “ - 因此成为发送 Git,现在原始发件人成为接收者,并且必须再次做同样的事情。所以相反,在Git 实现接受或拒绝的情况下,没有中间版本:接收Git只是拒绝该尝试,现在由发件人决定是否纠正问题。
(实际审核过程实际上只在push
上运行,因为fetch
只是将新提交放在一个地方,你的存储库控制者可以在存储它们之前检查它们。 em>你的名称。即使它们进入全局名称空间,也几乎没有对fetch上的标签进行审查:你已经拥有的任何标签都被保留,拒绝尝试存储新标签,但是任何标签你没有被接受和存储,如果你决定讨厌它们,你必须手动撕掉它们。)
GitHub有自己的Git存储库,GitHub 可以进行这种审查:确保传入的推送提交具有与用户名和电子邮件地址匹配的有效用户名和电子邮件地址。存储在帐户信息中的电子邮件地址,无论是谁进行推送,都会将自己的身份验证为 。这只是传统的不打扰,因为这对于聚集他人工作的人来说也是一种痛苦,因此推动故意给予原作者信誉的承诺。人们可能也不得不在初始推动时绕过它,为许多作者创建一个现有的,长期运行的项目创建一个新的GitHub存储库。
请注意,您向GitHub提供的内容不是 用户名和电子邮件地址,而是:它是某种身份验证凭据(例如ssh密钥或限时认证cookie)。它告诉GitHub你知道某种共享秘密:你(可能)你。 (GitHub 保留映射:ssh键映射到GitHub帐户,GitHub显然有一个与该帐户关联的电子邮件地址。)
答案 1 :(得分:1)
如果您的工作电子邮件地址为foo
,请考虑当您在GitHub上的用户名为bar@example.com
时会发生什么。如果Git或GitHub在身份和电子邮件地址之间强制执行直接映射,那么您如何期望Git能够可靠且可靠地处理此问题?
如果您的名字是John Q. Public
,您在localhost上的用户名为john-public
,而您的GitHub帐户是jpublic
,该怎么办? Git应该如何处理跨系统的这些差异?
Git不能,所以Git没有。相反,Git将提交数据和身份验证视为单独的事物。
存储在Git提交对象中的数据和您向GitHub呈现的credentials根本不是相同的事情。您认为您的用户名或电子邮件地址是您在Git中的身份,但他们实际上与Git或GitHub中的身份验证或授权无关。 您向GitHub呈现的凭据是您的GitHub用户名和密码,或您的GitHub用户名和SSH密钥,与您当地用户名或电子邮件地址的任何关系都纯属巧合。
如果您在安装了NFS的共享上使用Git,在项目的整个生命周期内为不同的公司工作,一次为多家公司工作,或者需要将工作和非工作项目保持逻辑分离,学会欣赏Git的电子邮件归属机制既灵活又便携。
请记住,Git是一个内容跟踪器,而不是一个身份验证系统。您使用第三方(如GitHub)进行的大多数身份验证实际上是使用SSH或HTTPS协议在Git之外进行的,这两种协议都不关心提交对象中的字段。
其中一个是我需要显式配置user.name和user.email参数(或者任何正确的术语,它似乎没有在文档中提及,像许多其他事情一样)。也许这是有道理的,因为当我在本地提交时,我不需要提供凭证。但实际上,当我推送我的更改并且只接受设置的任何user.name值而不检查它是否与我的登录匹配时,它确实要求我的凭据。然后GitHub在其他人的名字下显示我的更改,这非常令人困惑。
您正在混淆许多非常不同的问题。下面列出了一些比较明显的,但肯定有其他的。
一般而言,Git决定将身份验证与作者或提交者详细信息分开是一个很好的可移植性。您可以在不同的系统或项目上拥有不同的用户名或电子邮件地址,并且在〜/ .gitconfig , $ GIT_DIR / .git / config 中保存时,您的身份信息相对便携,或适当的环境变量。