Git 中的提交永远不会改变。既不要变基也不要git commit --amend更改任何提交,因为这是不可能的。1
这里的技巧在于定义“提交”。你怎么知道哪个提交是哪个?如果我说“Git 的 Git 存储库中的一次提交”,那么,其中有超过 40,000 个提交。 我指的是哪一个?
\n\n我告诉你的明确而明确的方式是给你哈希 ID,例如9b7cbb315923e61bb0c4297c701089f30e116750。这是一个特定提交的真实名称:
$ git cat-file -p 9b7cbb315923e61bb0c4297c701089f30e116750 | sed \'s/@/ /\'\ntree 4ba58c32960dcecc1fedede9c9362f5c10158f08\nparent 77933f4449b8d6aa7529d627f3c7b55336f491db\nauthor Junio C Hamano <gitster pobox.com> 1418845774 -0800\ncommitter Junio C Hamano <gitster pobox.com> 1418845774 -0800\n\nGit 2.2.1\n\nSigned-off-by: Junio C Hamano <gitster pobox.com>\nRun Code Online (Sandbox Code Playgroud)\n\n该名称永久附加到该特定提交。不过,这确实是一个笨拙且丑陋的名字。有一个更短、更漂亮、更实用的名字不是很好吗?还有一个:我可以指出v2.2.1:
$ git rev-parse v2.2.1^{commit}\n9b7cbb315923e61bb0c4297c701089f30e116750\nRun Code Online (Sandbox Code Playgroud)\n\n但事实上,v2.2.1它根本不是一个提交,它是一个标签。具体来说,它是一个标记名称(在name 下的文件中refs/tags/v2.2.1或文件中找到)指向带注释的标记对象,2而不是直接指向提交:packed-refsv2.2.1
$ git rev-parse v2.2.1\n7c56b20857837de401f79db236651a1bd886fbbb\nRun Code Online (Sandbox Code Playgroud)\n\n标签对象内部有提交 ID,加上一大堆额外的内容,包括“PGP 签名”:
\n\n$ git cat-file -p v2.2.1 | sed \'s/@/ /\'\nobject 9b7cbb315923e61bb0c4297c701089f30e116750\ntype commit\ntag v2.2.1\ntagger Junio C Hamano <gitster pobox.com> 1418851265 -0800\n\nGit 2.2.1\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1\n\niQIcBAABAgAGBQJUkfPBAAoJELC16IaWr+bLjfgP/iA78fk3NkTEROoyIVq6kPDH\npZAlm4ObsKXAdl6sFqWe7xFxGExHYzJ5L3qGXs3VM+9Z3iDe2WZN3WbK3aFtYqfU\nAYRSTpnPzDf4L0vfyqiFS7//+LoeM2TogAV7SLdehMlodsL5HR6FiSz1zffSq8D0\nCi4XpGWHkqXLhfvUPC7foCgGpf7l38gsbJPbdkyKLK9/wtLSfkk45vK+wY6o3CCv\nJKBFr468958fvw+j73nxiT+Vne7TeL1Bq1kCq9M65dAjOpFjZiD408NaF7jTcNcx\nTMjdKoVlDNFHcUPMv9B5C308sRVUylmeUzb8XrQNji0+1NA5ivVgDfZsudWUtlTj\njo9xku0Np4IdXPwxJNlO5tC2rnof4gdD4jWPJj/DvellNKCDXuLuXDZSKZDI9GSr\nOzLsad8uFX3MySPe+evIVF6qGS2KzI8PGNrohqWaPkX8cug22EW7lKJFpjYJb5gP\n3nJUJvbsrMeyoH/GqxPzA5clqMGtsirnTiapMILNRmlC+3rzc0DkLw90BM6vKNOC\neDTOI9Xj1JS9qbD6fEkxVNrXRDz0TFbtpFbFTtKk4zfAc/jTOqE9fqpV7afoQfON\ne1NwrjR5Kcts7ev23Y0G1WH3t2L0N2/q27kcjrulCEH1vtXlmaZFU6o+WKUVV7iH\n/YQnjNUOgRxQ1zBGof7h\n=yJ4Q\n-----END PGP SIGNATURE-----\nRun Code Online (Sandbox Code Playgroud)\n\nPGP 签名让我们决定是否相信 Junio C Hamano 真的制作并签署了这个标签。它使用比 SHA-1 更强的加密数字签名形式(这很好,因为 SHA-1 至少在理论上是可破解的),还支持分布式验证和撤销签名的能力( SHA-1 本身就是这样做的)不是)。
\n\n但最终,这只会对我们有帮助我们信任和/或可以验证的人制作了这样的 PGP 签名标签,或者已经对 PGP 签名的提交进行了 PGP 签名时,这才对我们有帮助。理论上,对每个提交进行签名可能会更强一些,因为这样就可以直接在提交上进行数字签名;但在实践中,签名标签要方便得多,而且同样好,因为我们不经常破坏 SHA-1(而且,至少使用当前的强力方法,如果我们这样做,它会留下明显的标记,尽管)这远远超出了这个答案的范围,而且也超出了我正确描述的范围\xe2\x80\x94密码学不是我的领域)。
\n\n1嗯,如果你能破解 SHA-1 哈希,理论上是可能的。如果你想出一个新的、不同的对象,但它产生相同的哈希值,Git 的行为方式意味着,如果你已经拥有旧的对象,你将永远不会选择这个新对象。此规则适用于所有 Git 对象(提交、树、带注释的标签和 blob),所有这些对象均按其哈希值命名。
\n\n为了让他们看起来git rebase像是更改了提交,要做的就是制作现有提交的新副本,然后将名称打乱。新提交具有新的、不同的哈希值,并且由于后来的(后代)提交实际上包含其直接祖先(父级)提交的哈希值,因此“更改”一个提交的哈希值(即,将提交对象复制到新的,不同的提交对象)强制更改通过其余提交向下冒泡。然后,我们将现有的(短、分支或标签)名称重新指向新链的顶端。git commit --amend
这就是为什么,给定一个我们认为可信的端点,我们可以将该信任扩展到链或树中的每个先前对象。其技术术语是默克尔树。
\n\n2这就是 Git 所说的“带注释的标签”:一个标签名称(它本身就是一个“轻量级标签”),指向一个带注释的标签对象,存储在 Git 存储库中,该标签对象指向其他一些Git 对象\xe2\x80\x94 通常是一个提交,但也可能是另一个标签,甚至是一棵树或一个 blob。然而,即使“另一个标签”也有点罕见\xe2\x80\x94,Git\xe2\x80\x94 的 Git 存储库中只有其中三个,而另外两个几乎是闻所未闻的。
\n| 归档时间: |
|
| 查看次数: |
1407 次 |
| 最近记录: |