交互式变基时git修复和drop + reword有什么区别吗?

7ajki6be  于 2023-01-11  发布在  Git
关注(0)|答案(4)|浏览(156)

我已经开始更多地研究交互式重定基,并且遇到了一些问题。它们是关于“修正”选项的。我对fixupdrop + reword选项之间的区别很感兴趣。例如,假设我们有:

pick 577dab2 add navbar
pick 432fda1 fix navbar bug

这两者之间的区别是什么:

pick 577dab2 add navbar
fixup 432fda1 fix navbar bug

以及

drop 577dab2 add navbar
reword 432fda1 fix navbar bug -> reword it to 'add navbar'

如果fixup选项在“合并”时提供冲突解决方案(如果存在),则会产生不同效果(我知道这不是真实的的合并,但我们就这么叫吧)与之前的提交(在我的例子中,如果577dab2432fda1提交之间有任何冲突)然而,就我所注意到的,实现只是“meld into”,也就是说,fixup提交(432fda1)中的所有内容只会被“转移”到前一个提交(577dab2)中,并且会使用前一个提交(577dab2)的名字。换句话说,即使存在冲突,也不会得到解决,因为所有内容都只是从一个提交“转移”到另一个提交。
所以从我目前的理解来看,fixup只是允许同样的事情做得更快...谁能告诉我真实的的区别是什么(如果有的话)?
8年前有人问过这个问题,但没有人回答,至少没有人完全回答。

sg3maiej

sg3maiej1#

你的误解是关于rebase如何工作的概念上的。rebase基本上只是挑选一系列提交中包含的每一个 * 修改 *(因此在交互式rebase中使用了“pick”一词)。注意,当挑选或rebase时,你关于达到提交的原始 * 状态 * 的想法是不相关的。
考虑到这一点,请考虑以下差异:

pick aaaaaaa Add file A
pick bbbbbbb Add file B
# RESULTING COMMITS: 2 commits with those titles
# RESULTING STATE:   File A and File B both exist.

pick aaaaaaa Add file A
fixup bbbbbbb Add file B
# RESULTING COMMITS: 1 commit with title "Add file A"
# RESULTING STATE:   File A and File B both exist.

drop aaaaaaa Add file A
reword bbbbbbb Add file B
# RESULTING COMMITS: 1 commit with default title "Add file B", but pops up editor
#                      and allows you to change it
# RESULTING STATE:   Only File B exists.

同样的概念也适用于编辑同一个文件的两次提交,只是现在我们引入了冲突的可能性。假设我们有一个名为file1的文件,其中包含一个字符'x',现在我们有两次提交只是修改了这个字符:

pick aaaaaaa Change file1 to 'a'
pick bbbbbbb Change file1 to 'b'
# RESULTING COMMITS: 2 commits with those titles
# RESULTING STATE:   file1 is 'b'

pick aaaaaaa Change file1 to 'a'
fixup bbbbbbb Change file1 to 'b'
# RESULTING COMMITS: 1 commit with title "Change file1 to 'a'"
# RESULTING STATE:   file1 is 'b'

drop aaaaaaa Change file1 to 'a'
reword bbbbbbb Change file1 to 'b'
# CONFLICT! This is because commit bbbbbbb only knows how to change
#   from 'a' to 'b', but right now the starting point is 'x' instead of
#   'a', so it pauses and asks for your help. Most likely you'd want to 
#   take 'b' in this case, and then:
#
# RESULTING COMMITS: 1 commit with default title "Change file1 to 'b'",
#                      but pops up editor and allows you to change it
# RESULTING STATE:   file1 is 'b'
lc8prwob

lc8prwob2#

这两者之间有什么区别
drop是一个非常强大的选项,它可以向所有后续提交传播一个重大更改,这样被丢弃的提交相对于其父提交所代表的“更改”将 * 永远不会发生 *。
pick正好相反,它将那些“更改”保留在历史中。
的确,你比较的两个选择没有实质性的共同点,我不明白你为什么要问它们之间的区别;他们缺少的是相似之处。

bvuwiixz

bvuwiixz3#

是的,一个巨大的区别。如果你drop第一次提交,它...丢弃第一次提交。无论在那次提交中做了什么改变,你正在修复的东西将不会在那里修复,第二次提交可能不会应用,如果它应用了,它可能是无效的。

cyvaqqii

cyvaqqii4#

它们***不***等价。
我认为混淆之处在于,当使用交互式重定基时,你处理的是一组单独的更改,而不是提交之前的完整内容。
当你说drop 577dab2 add navbar的时候,就好像那个提交 * 从来没有发生过 *。没有导航栏供432fda1修复。

pick 577dab2 add navbar
fixup 432fda1 fix navbar bug

你在说“假装我从来没犯过那个错误而且第一次就做对了”。
这将把两个提交中的修改变成一个单独的提交,并使用选中的提交的日志消息。您将在一个单独的 new commit 中完成577dab2和432fda1中的修改,并且只显示“add navbar”日志消息。

drop 577dab2 add navbar
reword 432fda1 fix navbar bug -> reword it to 'add navbar'

你说“假装577dab2从来没有发生过,我从来没有添加过导航栏”(我忽略了重述,这是不相关的)。
这将抛出在577dab2中所做的更改(添加导航栏),您只剩下432fda1中的更改。由于432fda1正在尝试修复从未添加的导航栏,因此您可能会遇到冲突。
该实现仅被“合并”,即,修正提交(432FDA1)内的一切将仅被“转移”到先前提交(577DAB2),并且将采用该先前提交(577DAB2)的名称。
旁注:Git***从不***修改提交,它只会创建新的提交。
假设您的回购协议是这样的。

A - B - C - D - E [main]

假设你fixup C.Git创建了一个包含B和C中的修改的新提交,并在新提交的基础上重写了D和E中的修改。

A - B - C - D - E
 \
  BC - D1 - E1 [main]

旧的B、C、D和E提交将被垃圾收集。
更多关于为什么它会这样工作,请参见什么是Git提交ID?。
但是如果你说drop B,Git会尝试在A上重写C,就好像B从未发生过一样。

A - B - C - D - E
 \
  C1 - D1 - E1 [main]

C中的更改现在应用于A。如果C的更改依赖于B(如修复B引入的导航栏),则您将遇到冲突。
让我们换个Angular 来看,假设577dab2是这样的。

--- a/dir1/file
+++ b/dir1/file
@@ -11,3 +11,8 @@ and some more
 and here is more
 
 and then this
+
+from the first commit
+
+Back Home Escape Next
+

而432fda1是这个。

--- a/dir1/file
+++ b/dir1/file
@@ -14,5 +14,6 @@ and then this
 
 from the first commit
 
-Back Home Escape Next
+Back Home Leave Next
 
+from the second commit

你就去撮合...

pick dedbeef something else
pick 577dab2 add navbar
fixup 432fda1 fix navbar bug

结果是一个包含577dab2和432fda1的变更的 * 新提交 * 以及577dab2的提交消息。

--- a/dir1/file
+++ b/dir1/file
@@ -11,3 +11,9 @@ and some more
 and here is more
 
 and then this
+
+from the first commit
+
+Back Home Leave Next
+
+from the second commit

但如果你放弃577dab2而改写432fda1...

pick dedbeef something else
drop 577dab2 add navbar
reword 432fda1 fix navbar bug

这与删除577dab2并尝试在dedbeef上应用432fda1中的更改相同。

pick dedbeef something else
reword 432fda1 fix navbar bug

dedbeef没有“Back Home Escape Next”行可供更改,因此这将导致冲突。

相关问题