还原不在当前分支中的git提交

还原不在当前分支中的git提交,git,git-revert,Git,Git Revert,我有两个分支:master和feature • master • feature 我在特性分支上做了两次提交 • master • C1 • C2 • feature 现在,我想在master中合并功能。我使用git merge--squash特性来合并 • C3 • master // C3 is the squashed commit • C1 • C2 • feature 此时,是否有办法从主机还原C1 一个选项是在功能上还原C1,并在主控中再次挤压合并功能。是的,您可以使用

我有两个分支:master和feature

• master
• feature
我在特性分支上做了两次提交

• master
• C1 • C2 • feature
现在,我想在master中合并
功能。我使用
git merge--squash特性来合并

• C3 • master     // C3 is the squashed commit
• C1 • C2 • feature
此时,是否有办法从主机还原
C1


一个选项是在功能上还原
C1
,并在主控中再次挤压合并功能。

是的,您可以使用
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和其父级之间的差异,并将其作为主节点上的补丁应用吗?比如说,如果你不能在主节点上恢复C1,那么在你的特性分支上恢复它,然后在主节点上选择/重定提交的基址怎么样?如果可能的话,我只需将C1恢复到C1之上,并将其重新设置(移动)到master上。@LasseVågsætherKarlsen master是构建分支,所有功能分支都将在其中合并。我更喜欢压缩合并,这样我就可以在需要的时候很容易地恢复一个功能。同样的原因,重定基址也不会有帮助,因为恢复整个功能很容易。很好的解释+1.
> 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