我从其他开发者那里挑选了一份承诺来做一些工作。
几个小时后,一名开发人员更新了他的补丁。
如果我选择新补丁,则存在冲突。
有什么办法可以丢弃以前的补丁,还是必须手动解决冲突?
答案 0 :(得分:2)
您有两个直接且显而易见的选择:
添加第二个提交,以撤消第一个选择。 (现在,您有了一个源快照,看起来好像您从未进行过第一次采摘。)
删除第一个选择,即更改提交历史记录。
使用哪种方法取决于很多事情,包括您是否说过“永远不要重写任何历史”(在这种情况下,您必须使用第一种方法),或者您是否拥有除承诺之外的其他承诺。按图顺序选择一个。
请记住,每个Git提交均由其哈希ID唯一标识。如果我们使用大写字母表示这些提交(而不是原始哈希ID),则可以更清楚地了解正在发生的事情。例如,假设我们从以下一系列提交开始:
... <-F <-G <-H <--yourbranch (HEAD)
\
I <-J <--origin/theirbranch
然后,无论出于何种原因,您都决定喜欢他们的提交J
,因此您运行git cherry-pick <hash-of-J>
或git cherry-pick theirbranch
。 复制提交J
的效果,进行新的提交。我们可以将此提交称为K
,但让我们使用J'
来表示它是J
的副本:
...--F--G--H--J' <-- yourbranch (HEAD)
\
I--J <-- origin/theirbranch
在将来的某个时刻,无论他们是谁,他们都放弃了他们的提交J
,而选择了新的和改进的提交K
,因此在运行git fetch
之后,您可以有:
...--F--G--H--J' <-- yourbranch (HEAD)
\
I--K <-- origin/theirbranch
(提交J
已完全消失:新提交K
直接指向I
。这是人们谈论的“历史重写”。)
此时,您可以使用git reset --hard
重写自己的历史记录。当然,这会丢弃您正在做的任何工作,但是让我们假设您没有做任何新工作,这样就可以了:
J' [abandoned]
/
...--F--G--H <-- yourbranch (HEAD)
\
I--K <-- origin/theirbranch
您现在可以更轻松地选择他们的提交K
,因为它与您的原始J'
的副本J
不冲突。这样您将拥有:
J' [abandoned]
/
...--F--G--H--K' <-- yourbranch (HEAD)
\
I--K <-- origin/theirbranch
但是,另一方面,假设您要做的工作取决于您的J'
的{{1}}副本。例如,假设您从挑选他们的J
到完成J
之后又做了六次提交?然后,您现在有了 this :
J'
现在要摆脱...--F--G--H--J'-L--M--N--O--P--Q <-- yourbranch (HEAD)
\
I--K <-- origin/theirbranch
更加困难:它已嵌入到您的 历史中,该历史从J'
一直延伸到{{1} }。
您可以使用交互式变基(Q
)通过将提交F
复制到很多新的提交git rebase -i
中来尝试将J'
从历史记录中删除>喜欢原稿,但跳过L-M-N-O-P-Q
:
L'-M'-N'-O'-P'-Q'
(请注意,这看上去很像是反复摘樱桃。那是因为J'
就是反复摘樱桃!)但是,如果这样做太痛苦或令人反感,出于其他原因,您现在可以进行新的提交 J'-L--M--N--O--P--Q [abandoned]
/
...--F--G--H--L'-M'-N'-O'-P'-Q' <-- yourbranch (HEAD)
\
I--K <-- origin/theirbranch
,使它们的副本git rebase
与其原始R
的副本J'
的效果 ,并将其添加到您的分支中:
J
通过运行以下命令,新提交...--F--G--H--J'-L--M--N--O--P--Q--R <-- yourbranch (HEAD)
\
I--K <-- origin/theirbranch
可能很容易(也可能不容易)
R
git revert <hash-of-J>
命令告诉Git:找出给定提交中的更改,并进行新的提交,以撤消这些更改。对于我添加到某个文件的每一行,请从该文件中删除该行。对于我从文件中删除的每一行,请将该行放回去。对于我批量删除的每个文件,请将该文件重新带回;对于我从头开始创建的每个文件,请完全删除该文件。
此过程完成后,提交git revert
中有一个快照,看起来好像从未发生提交R
。 (如果您的提交J'
至L
中的更改与此撤消Q
的尝试冲突,则通常会在还原过程中看到合并冲突。请注意 if 就是这种情况,如果在复制J'
至J'
时使用交互式变基丢弃提交L
,通常会看到 same 冲突。到新的提交。)