如何手动指定git提交记录的sha值?

3

这个答案解释了通常情况下git提交SHA是基于各种参数生成的。然而,我想知道:如何在Bash中指定自定义/特定的git提交SHA?

例如,假设有人想要创建并推送一个具有以下SHA的提交到Git:

1e23456ffd118db9dc04caf40a442040e5ec99f9
< p >(为简单起见,假设可以假定它是唯一的sha)。

XY问题是两个不同Git服务器之间的手动镜像脚本。与在Git服务器之间保持提交映射相比,拥有相同的提交SHA更加方便。这是因为如果我可以跳过来自source服务器的某些提交,则手动镜像更有效(节省计算时间和服务器带宽)。然而,这意味着父提交会相对于source服务器中的同一提交在target服务器中发生变化。反过来,这将意味着SHA发生变化,这将要求我跟踪sourcetarget服务器中的sha映射。简而言之,仅覆盖提交的sha到target服务器比确保两个服务器具有完全相同的提交更方便(对于实际上被镜像的少数提交)。


1
指定提交 sha 不是预期的。我猜你想要的是类似于 git tag 的东西。 - Jonathan Weine
6
这是一种无法选择但被确定下来的东西。你为什么想要这个呢?也许你可以制作一个特定的提交信息,以产生相同的哈希值。 - CodeCaster
1
Git的设计并不允许你选择SHA(Secure Hash Algorithm),除非用一种方式。你可以仔细构造提交的内容来生成SHA。然而,这非常困难和昂贵。当我说“非常”时,如果你在这里问如何做到这一点,基本上说明你不知道如何做到,所以你做不到。这是研究级别的难度。据我所知,只有少数成功的尝试创建哈希碰撞,即构建出两个不同的提交,但它们具有相同的SHA。从零开始到达一个SHA,我认为还没有被做到过。 - Lasse V. Karlsen
1
所以,为了让你更容易理解我的评论:Git不是这样工作的,你不能这样做,所以你可以忘记那种便利性,想出一种不同的处理方式来应对你的情况。 - Lasse V. Karlsen
4个回答

2
一个提交的SHA值不仅仅是基于那些参数“正常”生成的,而且根据定义它是这些参数的哈希值。“SHA”是用于生成它的哈希算法的名称。
与其试图“更改”提交哈希值,你应该寻找一种有效的方法来“跟踪”它们。一种方法类似于像git svn这样的插件:
- 在将提交复制到镜像时,将原始提交哈希记录为新提交消息的一部分。 - 可能,由于你在原始存储库中“跳过”了提交,每个新提交应该有多个源哈希,因为它将像这些提交的“压缩”一样。 - 有一个脚本可以处理git log的结果并提取这些记录的提交哈希。这可以在确定从源复制哪些新提交时使用,而不是真实的提交哈希。
然而,请确保这一切都是值得的:如果最终的更改都被包含在内,那么git现有的去重和压缩技术可能意味着“跳过”的提交所带来的额外负担相当低。

谢谢,我经常对解决问题的创造性表示敬畏!将“源”提交的sha作为“目标”提交的提交消息编写,这种方法简单而优雅(在我看来)。这可以避免我不得不保持单独的簿记,但仍然存储信息(在“目标”服务器中)。 - a.t.

1
从CodeCaster的评论中,似乎我可以在`git commit -m“some message”`中使用自由选择的位来确保提交的sha以特定值结尾。
然而,基于Lasse V. Karlsen的评论,我认为这种方法需要非线性计算资源。我没有详细研究这个问题,但我想象/假设随着提交历史的增长,提交消息中的(有限的(5mb))自由选择位的相对影响变得越来越小。我想这可能是利用提交消息中这些自由选择位变得昂贵的原因之一。
因此,在实践中,答案似乎是:“你可以(也许,如果你花费大量计算资源),但你不应该这样做”。。

1
由于您在问题中已经概述了您处理差异的方法,我将假设这个问题实际上只是:“我想知道如何指定一个自定义/特定的git提交sha(在Bash中)”,而不是“或者您有任何其他我可以使用的想法”。
对于这个问题,答案实际上非常简单:您不能。
Git不仅仅是计算提交ID,因为那只是所选择的实现方式的副产品。它的实现方式是Git设计的核心概念
提交ID是基于提交内容计算的,这包括你所观察到的父链接。改变父链接但保持其他所有内容相同,提交ID仍然会改变。
这是版本控制系统分布式部分工作的核心,不能更改。
你无法更改提交的ID并保持其内容不变。这是设计上的要求
曾经有一些尝试通过精心构造不同的提交来进行提交冲突,最终得到相同的ID。
以下是一个成功的尝试(冲突):https://www.theregister.com/2017/02/23/google_first_sha1_collision/

历史上第一个SHA-1哈希碰撞被计算出。只需要五个聪明的大脑……和6610年的处理器时间。

我不相信有人已经成功地将任意提交与特定提交ID配对。这些冲突是通过同时按照非常具体的标准操作两个提交来精心构造的,以便它们到达相同的ID,但该ID并不是由研究人员选择的。
总之,它无法完成。
生成的冲突的净效果是Git将在某个时候远离SHA-1,并采用产生比今天更长、更“安全”的哈希值的系统。由于Git还想向后兼容现有的存储库,因此这项工作尚未完全完成。

为了有意地这样做,您需要能够对SHA-1进行“第二前像攻击”。如果我理解正确,这种攻击的复杂度约为O(2^159)。或者在实践中完全不可行,因为太阳在其100亿年寿命期间产生的总能量甚至不足以用于暴力破解此类复杂度所需的理论最小能量。 - Mikko Rantalainen

0
如何在Bash中指定自定义/特定的git提交sha?
不能。提交哈希是通过将各种值进行哈希构造的值,其整个目的是唯一标识特定提交。您可以在不同时间和不同机器上提交相同的文件,并且最终会得到不同的提交哈希。
确保在两台不同的机器上具有相同的提交方式是从一台机器到另一台机器git pull(或类似)这些提交。您不一定需要移动所有提交-例如,您可以压缩它们或挑选只有某些提交。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接