是的,你可以使用
merge --squash
来还原某些提交,即使它已经包含在聚合中。
git-revert
的工作原理是通过识别在您指定的提交中引入的更改,然后创建一个新的更改来撤消(“还原”)这些更改。
它使用三路合并算法来实现这一点——以要还原的提交作为基础,然后与该提交的祖先和当前提交(
HEAD
)进行比较。这将隔离仅在该提交中引入的更改。
举个非常牵强的例子,假设你有一个文件,其中包含三个更改(
C0
,
C1
和
C2
),这些是每个版本的内容:
| C0 | C1 | C2 |
|-------|-------|-------|
| one | one | one |
| two | 2 | 2 |
| three | three | three |
| four | four | FOUR |
现在,如果您想还原
C1
,我们将其设置为基础,并将
C0
和
C2
作为每个侧面以获取更改。在三方合并算法中,您会查看每个侧面与基础的比较。如果所有三行都相等,则将该行不经修改地放入结果中。如果一侧进行了更改,则将更改后的行放入结果中。如果两侧在同一行上进行了更改,则将该行标记为冲突。设置还原操作会给您带来:
base sides result
---- ----- ------
one
/ two \
/ three \
one / four \ one
2 two
three three
four \ one / FOUR
\ 2 /
\ three /
FOUR
你可以看到结果(右侧)撤消了在
C1
中引入的更改,因为其中一侧(在本例中是
C0
)是唯一的,所以它的更改被保留在结果中。这具有撤销(“还原”)其中引入的更改的逻辑效果。
即使你进行了压缩合并,这也是正确的 - 在这种情况下,它正在查看存储库的内容。 CM
没有实际上将 C1
作为公共祖先,这并不重要。
你可以在一个简单的存储库中证明这一点,并验证在压缩合并之后仍然成立。
commit 9e7497c7ae34aa35cdb7d7b965a00d56bf0b9dfa
Author: Edward Thomson <ethomson@edwardthomson.com>
Date: Thu Nov 9 10:20:31 2017 +0000
Squashed commit of the following:
commit 8a8a9e73e62e21683e15269d89e1fbfbbf35cfa1
Author: Edward Thomson <ethomson@edwardthomson.com>
Date: Thu Nov 9 10:20:18 2017 +0000
C2
commit d984b27140e48c5faa8968364c415d29dcd7034c
Author: Edward Thomson <ethomson@edwardthomson.com>
Date: Thu Nov 9 10:20:08 2017 +0000
C1
您仍然可以正确撤销其中一个组件。在这种情况下,我会撤销C1
:
> git revert d984b27
[master 405f108] Revert "C1"
1 file changed, 1 insertion(+), 1 deletion(-)
> git show HEAD
commit 405f1080e24504fa418d423a0755a2123b85ecd8 (HEAD -> master)
Author: Edward Thomson <ethomson@edwardthomson.com>
Date: Thu Nov 9 10:20:42 2017 +0000
Revert "C1"
This reverts commit d984b27140e48c5faa8968364c415d29dcd7034c.
diff --git a/hello.txt b/hello.txt
index 9d980ae..14cf0bc 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,5 +1,5 @@
Hello, world!
one
-2
+two
three
four