假设我在分支主线上提交了A
,该分支当前未被推送(例如,因为正在对其进行代码审查)。
同时,我想基于提交B
开始开发新功能A
,因此我创建了另一个分支并开始工作。这是当前情况:
--- A
\
-- B
同时(例如,由于从代码审查中发现,我需要进行一些更改),因此我进行了一些更改以提交A
。我现在要修改提交A以包括新的更改。至少在我看来,提交B
会发生以下情况:
----- A
/
---- ?
\
---- B
?
是旧的,尚未修改的提交A
,现在不再存在。我认为这不是一个好主意。
那么正确的方法是什么?
我考虑过不修改A
,而是创建一个新的提交A'
:
--- A ----- A'
\
-- B
然后,当我准备推送功能A
时,先在A'
上选择B
,然后在B
上重新建立A'
:>
--- A -- A'
\
-- B
最后,挤压A
和A'
,然后按A
。
这似乎非常令人费解并且容易出错。另外,我完全不确定这是正确的方法。
有更好的方法吗?
答案 0 :(得分:0)
这就是为什么我一直告诉人们更改提交实际上是不可能的。
提交是由其原始哈希ID表示和找到的实体。您上面的A
和B
只是对实际的哈希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进行全新的提交,则可以强制执行副本。 ,但默认情况是检测到这种情况并尽可能保留。)
因此,evolutionxbox和phd在评论中都说过,您的情况是相同的:将名称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
。