修改一个Git提交,另一个分支从该提交产生

时间:2019-03-04 12:03:58

标签: git branching-and-merging

假设我在分支主线上提交了A,该分支当前未被推送(例如,因为正在对其进行代码审查)。

同时,我想基于提交B开始开发新功能A,因此我创建了另一个分支并开始工作。这是当前情况:

--- A
     \
      -- B

同时(例如,由于从代码审查中发现,我需要进行一些更改),因此我进行了一些更改以提交A。我现在要修改提交A以包括新的更改。至少在我看来,提交B会发生以下情况:

   ----- A
  /
---- ?
      \
       ---- B

?是旧的,尚未修改的提交A,现在不再存在。我认为这不是一个好主意。

那么正确的方法是什么?

我考虑过不修改A,而是创建一个新的提交A'

--- A ----- A'
     \
      -- B

然后,当我准备推送功能A时,先在A'上选择B,然后在B上重新建立A'

--- A -- A'
          \
           -- B

最后,挤压AA',然后按A

这似乎非常令人费解并且容易出错。另外,我完全不确定这是正确的方法。

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

这就是为什么我一直告诉人们更改提交实际上是不可能的。

提交是由其原始哈希ID表示和找到的实体。您上面的AB只是对实际的哈希ID的简短的,对人有用的替代,而这些哈希ID又长又笨拙。

如果您进一步绘制图形,它可能看起来像:

...--H--A   <-- mainline
         \
          B   <-- another

当您去“修改”提交A(大概使用git commit --amend)时,从根本上说,不可能更改它。您最终要做的是进行一次新的提交A',并且 commit A仍然存在,只是mainline不再指向它,也没有将其包含在其中从提示开始并向后工作即可达到的提交集:

       A'  <-- mainline
      /
...--H--A
         \
          B   <-- another

another唯一的提交集合,或等效地, another可到达的{em>可到达的提交集合{{ 1}},已经增长了,提交图本身没有任何变化。这是因为mainline本身已更改,因此可到达 mainline的提交集也已更改。

标签移动。提交不!

请注意,像mainline一样,git commit --amend也不会更改任何现有提交。相反,它(通常)复制提交,然后移动标签。 (“典型地”仅在这里是因为在某些情况下,rebase决定不需要执行任何工作并将现有的提交保留在原处。如果出于某些原因您希望使用新的哈希ID进行全新的提交,则可以强制执行副本。 ,但默认情况是检测到这种情况并尽可能保留。)

因此,evolutionxboxphd在评论中都说过,您的情况是相同的:将名称git rebase从提交mainline中删除之后,您将希望将提交A复制到其父为B的一些新B'

A'

最终-通常在将来30天或更长时间之后的某个时间,在放弃这样的一个或多个提交之后-Git将<垃圾回收不必要的提交。

使用 A' <-- mainline / \ ...--H B' <-- another \ A--B [abandoned, but remembered for some time] git rebase复制到B的棘手部分是,如果B'A之间存在实质性差异,您的Git将默认认为提交A'应该再次复制 ,产生或尝试产生:

A

A' <-- mainline / \ ...--H A"-B' <-- another \ A--B [abandoned, but remembered for some time] A'之间可能有很多合并冲突)。有多种方法可以防止这种情况发生,例如使用A"git rebase -i