假设我的本地分支上有以下版本历史记录:
A -- B -- C
Run Code Online (Sandbox Code Playgroud)
如何在 A 和 B 之间插入新版本 X,以便版本历史记录如下所示:
A -- X -- B -- C
Run Code Online (Sandbox Code Playgroud)
请注意,过去有一个关于如何插入提交的类似问题,但是,在我的情况下有点不同:X 引入的任何更改都不会传播到 B,在版本 X 插入 A 之间后,B 应该保持不变和B。
如果您想添加提交,但使其对源没有影响,那么是的,您确实需要与交互式变基不同的路径。
\n\n没有专门为此设计的东西,但它相对容易做到git replace:
A(作为分离的 HEAD,或者在新分支上,但新分支很快就会变得无用):git checkout <hash-of-A>。X(但是您希望它出现)。git replace --graft <hash-of-B> HEAD。你现在有了这样的真实历史:
\n\n X--B\' <-- refs/replace/<hash-of-B>\n /\nA--B--C <-- whatever-branch-this-is\nRun Code Online (Sandbox Code Playgroud)\n\n这些“替换”对象的特别之处在于,每当 Git 准备对几乎任何对象\xe2\x80\x94 执行几乎任何操作时,包括“出于任何目的使用提交”,例如 \xe2\x80\x94,Git 都会查找查看是否存在refs/replace/带有对象哈希 ID 的名称。由于有的替代品B,Git 现在将寻找B\'. 因此,git log其他 Git 命令的行为就像历史记录一样:
A--X--B\'--C\nRun Code Online (Sandbox Code Playgroud)\n\n但请注意,真实的历史记录仍然存在于该存储库中。当且仅当该refs/replace/名称位于存储库\xe2\x80\x94 中(当然是在此存储库\xe2\x80\x94 中)并且启用替换(默认情况下)时,才会使用替代历史记录。但是,如果您在其他地方克隆或推送此存储库,则获取或推送过程通常不会传输任何refs/replace/名称;因此该存储库的克隆将切换回旧历史记录。(您还可以通过禁用替换来查看原始历史记录,git --no-replace-objects log ...例如使用。)
如果您愿意,现在可以运行git filter-branch,它只是复制提交。默认情况下,git filter-branch遵循替换规则。这意味着当它复制分支上的提交时,它将以 开始A,然后复制X,然后复制B\',然后复制C指向B\'。A、X、 和的副本B\'将与原始版本逐位相同,因此实际上会重复使用原始版本;但 的副本C会略有不同:它将用作B\'其真正的父级,而不是作为替代的嫁接父级。因此,提交C将被复制到新的提交C\',并且分支名称(无论它是什么)都将指向新副本。
这个过滤后的分支具有实际的(不仅仅是嫁接的)历史记录,可以遍历到 to ,因此B\'现在如果您克隆过滤后的存储库,克隆中看到的历史记录同样会从到 开始并返回到to 。XAC\'B\'XA
| 归档时间: |
|
| 查看次数: |
1252 次 |
| 最近记录: |