假设我只有一个分支,我的提交历史是:
A - B - C - D
如果我在 GUI(如 GitKraken 或 Windows 版 Git)中单击 C 并执行“还原提交”,我会收到一条文件冲突消息。
两个问题:
这是因为还原“撤消”了在 C 和 GIT 中所做的更改吗 现在卡在 B 和 D 中,它们以不同的方式修改文件, 不兼容的方式?是这个原因吗?
如果是,这是否意味着您只能还原最后一个 犯罪?除了最后一次,你能恢复提交吗? 不产生冲突?
更新
在@RomainValeri 提供非常有用的说明后编辑问题。我想我在恢复和重置之间混淆了太多。在他下面的例子中,做
git revert B
导致分支从
A-B-C-D
到
A-B-C-D-E
如果 B 是唯一更改了 file2.txt 的提交,并且 B 没有对其他文件进行任何其他更改,那么在还原之后创建的新提交 E 将保留 C 和 D 中所做的所有更改但不是 B 制造的。这是正确的吗?
这是因为,从技术上讲,恢复意味着取消、撤消提交的任何更改 - 这是正确的吗?
另外:假设我的工作目录中只有一个文件。如果 B 是唯一更改我文件中函数 fun1() 的提交,而所有其他提交更改同一文件中的其他函数,那么还原 B 很可能会导致冲突 ,因为 git 根据文件中的行来思考,而不是根据文件中的函数来思考。这是正确的吗?
假设 B 更改了 fun1(),C 更改了 fun2(),D 更改了 fun3()。然后我意识到在 B 处在 fun1() 中所做的更改是错误的,我需要撤消它们。 如果所有这些函数都在同一个文件中,有没有办法撤消 B 中的更改,同时保留 C 和 D 中的更改?
相反,如果这 3 个函数中的每一个都在一个单独的文件中,那么在不影响其他提交的情况下撤消一个提交的更改会简单得多,对吗?
我想这当然是为什么单个文件永远不能太大,也不能包含太多函数来做不同事情的众多原因之一,对吧?
最佳答案
简短回答:是的。您可以很好地恢复给定的提交(即使是旧提交)并且没有冲突。
为什么会这样?
git revert
在树的当前顶端创建一个新的提交,它不会删除给定的提交,也不会以任何方式修改它。
当 merge-base 中的某些内容不同时,您就会发生冲突在您使用还原和 HEAD
创建的提交之间。
亲自尝试一下
简单的例子
给定 repo 树,
Folder1
file1.txt
file2.txt
Folder2
file3.txt
和以下历史,
A---B---C---D << HEAD
在哪里
A
创建所有文件及其内容。
B
修改file2.txt
C
修改file1.txt
和file3.txt
D
进一步修改file1.txt
然后是命令
git revert B
不会产生任何冲突,只是一个全新的提交 E
对 file2.txt
进行了新的更改。
A---B---C---D---E << HEAD
git revert
创建的新提交的内容(在评论后添加)
E
中的更改与 B
中引入的更改完全相反。
像这样使用B
:
$ git show B
commit f3ba29d98c0998297126d686d03d33794cbc0f73
Author: Pythonista <some.name@some.isp>
Date: Sun Mar 24 20:41:49 2019 +0100
Some change
diff --git a/javascript/functions.js b/javascript/functions.js
index 543c9cb..5f166d3 100644
--- a/javascript/functions.js
+++ b/javascript/functions.js
@@ -3710,5 +3710,6 @@ function dumpLists(isMixted) {
// end of process
createTrigger(window, 'load', START_EVERYTHING);
+doStuff(param);
你会有一个 E
提交包含:
$ git show E
commit 2ff723970e81d64f3776c081a1f96242589774b6 (HEAD -> master)
Author: Pythonista <some.name@some.isp>
Date: Sun Mar 24 20:42:33 2019 +0100
Revert "Some change"
This reverts commit f3ba29d98c0998297126d686d03d33794cbc0f73.
diff --git a/javascript/functions.js b/javascript/functions.js
index 5f166d3..543c9cb 100644
--- a/javascript/functions.js
+++ b/javascript/functions.js
@@ -3710,6 +3710,5 @@ function dumpLists(isMixted) {
// end of process
createTrigger(window, 'load', START_EVERYTHING);
-doStuff(param);
注意最后一个 diff 行前面的 +
或 -
,意思是“添加”(+) 和“删除”(-)。
最后,在您的帖子末尾谈谈您的担忧(出于某种原因,我大部分时间都错过了):
我认为您不应该根据对源代码控制的担忧来选择应用程序的架构。 Git 是一个非常棒的工具,它足够聪明,可以避免我们不可避免地遇到的大部分常见问题。寻求根据自己的逻辑对代码进行分组的最佳方法,而不管 git。
顺便说一句,冲突检测发生在 block 级别,而不是文件级别。这意味着同一个文件可能已经被两个源修改而不会引起冲突,如果它们发生在不同的非连续部分。我不能确切地说出阈值在哪里,但这与重点无关。
关于git - 您能否在不造成冲突的情况下恢复除最后一次提交以外的提交?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55322462/