Git: 如何修改 HEAD^^ 提交的内容(不是提交信息)

Git: how to modify the content (not commit message) for the HEAD^^ commit

假设我工作于:

我有以下提交

我做错了,我忘记将 file3 添加到提交 1。如何将 file3 的更改添加到提交 1?

一种方法是:

git reset --soft Commit 1
git add file3
git commit --amend 
git add file2
git commit -m "feature 2 completed"

我不想这样是因为事实上我可能不仅有提交 2 而且还有提交 3,4,5,6...

还有其他简单的方法吗?

谢谢

从技术上讲,您不能修改任何 提交。即使 git commit --amend 也不会那样做。请记住,每个提交都由其哈希 ID 唯一标识。

可以做的是获取一些现有的提交,提取它,然后用它来构建一个新的,不同的提交几乎 与原始提交相同,但无论您认为有缺陷的是什么,都已修复。然后你必须说服每个人——你自己,以及任何克隆了提交的人——停止使用旧的、有缺陷的提交,而是使用闪亮的新提交。新提交有一个新的、不同的 哈希 ID。

如果闪亮的新提交 而不是 在分支的顶端——如果它向后退了两步,例如在这种情况下——那么你还有一个额外的问题。请记住,像 masterdevelop 这样的分支名称标识 一个特定的提交 ,Git 调用 提示 分支的提交。每个提交还包含其 parent(先前)提交的哈希 ID,这就是 Git 从最新提交中查找较早提交的方式:

...--D--E--F--G   <-- master
         \
          H--I--J--K   <-- develop

在这里,大写字母代表丑陋的大哈希 ID。名称 master 标识提交 Gmaster提示。名称 develop 标识提交 Kdevelop 的提示。从提交 G,Git 可以向后工作到 F,然后是 E,依此类推。从 K、Git 可以倒推到 J,最终到 E 等等。

如果提交 I 有问题,你可以做的是 Git 提取提交 I,对 index-and-work-tree 对进行一些更改(只是就像你对任何其他提交所做的那样),然后进行 new 提交——我们称它为 I' 以表明它是 I 的替代品——其 parent 与 I 的 parent:

相同
...--D--E--F--G   <-- master
         \
          H--I--J--K   <-- develop
           \
            I'  <-- temporary

完成后,我们现在只需要 Git 将 J 复制到一个闪亮的新 J',其 parent 是 I' 并且其效果I'JI 的影响相同:

...--D--E--F--G   <-- master
         \
          H--I--J--K   <-- develop
           \
            I'-J'  <-- temporary

现在我们重复 K 的技巧,使 K':

...--D--E--F--G   <-- master
         \
          H--I--J--K   <-- develop
           \
            I'-J'-K'   <-- temporary

最后,我们告诉Git:删除临时名称。使名称 develop 标识闪亮的新提交 K' 而不是令人讨厌的旧 K 这给了我们:

...--D--E--F--G   <-- master
         \
          H--I--J--K   [abandoned]
           \
            I'-J'-K'   <-- develop

并且如果我们停止绘制 废弃的分支,它看起来好像我们已经以某种方式更改了 三个提交。但我们没有:新的提交有新的、不同的哈希 ID。

...--D--E--F--G   <-- master
         \
          H--I'-J'-K'  <-- develop

这就是 git rebase -i 所做的。这听起来工作量很大,在某些情况下确实如此,但通常 git rebase -i.

变得轻松无痛

请注意,如果您已将 develop 推送到其他地方,您现在必须 force-推送此新开发,以告知其他收到提交的 Git IJK 它应该 忘记 那些提交(以及任何以后的提交!),而是使用闪亮的新替换.

如果其他用户选择了原始的 I-J-K 序列,您必须说服 他们 丢弃 他们的 I-J-K 副本也。如果他们在 K 之上构建了自己的提交,你必须让他们将他们的旧提交复制到你闪亮的新 K' 之上。对于所有其他用户来说,这可能是一项值得注意的工作量,因此请确保您真的想对他们执行此操作。