Git:如何修改HEAD ^^提交的内容(非提交消息)

时间:2018-07-17 07:54:23

标签: git git-commit amend

假设我从事过:

  • 功能1:file1 + file3
  • 功能2:file2

并且我有以下提交

  • 提交2:功能2已完成。
  • 提交1:功能1已完成。

我做错了,我忘记添加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 ...

还有其他简便的方法吗?

谢谢

1 个答案:

答案 0 :(得分:0)

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

您可以 做的是获取一些现有的提交,将其提取出来,然后使用它来构建一个新的几乎不同的提交,该提交几乎是 与原始提交相同,但是无论您认为有缺陷还是固定的。然后,您必须说服所有人(您自己以及克隆提交的任何人)停止使用有缺陷的旧提交,而改为使用闪亮的新提交。新提交具有一个新的不同哈希ID。

如果闪亮的新提交在分支的顶端是 not ,例如,如果向后退了两步(例如,在这种情况下),那么您将遇到另一个问题。请记住,诸如masterdevelop之类的分支名称标识一个特定的提交,Git将其称为分支的 tip 提交。每个提交还包含其 parent (上一个)提交的哈希ID,这就是Git如何从最新的提交中找到较早的提交的方式:

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

在这里,大写字母代表大的丑陋哈希ID。名称master标识提交Gmaster tip 。名称develop标识提交K,即develop的尖端。从提交G开始,Git可以向后依次工作到F,然后依次到E,依此类推。从K开始,Git可以向后退至J,最后退回到E,依此类推。

如果提交I中存在问题,您可以做的是让Git提取提交I,对索引和工作树对进行一些更改(就像您要做的那样) (对于其他任何提交),然后进行一次 new 提交(我们将其命名为I',以表示它是I的替代者,其父代与{{1 }}的父母:

I

这样做之后,我们现在只需要将Git复制...--D--E--F--G <-- master \ H--I--J--K <-- develop \ I' <-- temporary 到一个闪亮的新J上,它的父对象是J',并且对I'的影响与I'J的影响:

I

现在,我们重复...--D--E--F--G <-- master \ H--I--J--K <-- develop \ I'-J' <-- temporary 制作K的技巧:

K'

最后,我们告诉Git:删除临时名称。将名称...--D--E--F--G <-- master \ H--I--J--K <-- develop \ I'-J'-K' <-- temporary 标识为闪亮的新提交develop而不是旧的K'这样可以:

K

,如果我们停止绘制废弃的分支,就好像我们已经以某种方式更改 3次提交了。但是我们还没有:新的提交具有不同的新哈希ID。

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

...--D--E--F--G <-- master \ H--I'-J'-K' <-- develop 就是这样做的。听起来可能需要做很多工作,在某些情况下也可以,但是通常git rebase -i使 you 变得轻松而轻松。

请注意,如果您已将git rebase -i推送到其他位置,则现在必须 force -推动此新开发,以告知接收到提交develop,{{1 }}和I应该忘记这些提交(以及以后的所有提交!),而应使用闪亮的新替换项。

如果其他用户选择了原始的J序列,则必须说服他们丢弃他们的 K副本。如果他们在I-J-K上建立了自己的提交,则必须让他们将旧提交复制到闪亮的新I-J-K上。对于所有其他用户来说,这可能是相当多的工作量,因此请确保您确实要对他们这样做。