撤销当前分支之外的一个Git提交

3

我有两个分支:主分支和特性分支。

• master
• feature

我在功能分支上进行了两次提交

• master
• C1 • C2 • feature

现在,我想将 feature 合并到主分支。我使用 git merge --squash feature 来合并。
• C3 • master     // C3 is the squashed commit
• C1 • C2 • feature

此时,有没有一种方法可以从主分支中还原 C1

一个选项是在特性分支上还原 C1,然后再次将特性分支压缩合并到主分支中。


主分支和特性分支有什么关系?撤销提交只有在同一分支上才有意义(这意味着您可以从要应用撤销的点追溯回原始提交)。 - Lasse V. Karlsen
1
你能找到C1和它的父分支之间的差异,并将其应用为主分支的补丁吗?就像这个链接中所示:https://dev59.com/rGQn5IYBdhLWcg3wpYf0 - Martin Cook
如果您无法将C1还原到主分支的顶部,那么可以考虑将其还原到您的特性分支的顶部,然后在主分支上进行樱桃挑选/变基操作。如果这是可能的,我会简单地将C1还原到C1的顶部,并将其重新基于(移动)到主分支上。 - Lasse V. Karlsen
@LasseVågsætherKarlsen 主分支是构建分支,在其中所有功能分支都将合并。我更喜欢使用压缩合并,这样如果需要的话,可以轻松地撤销一个功能。 - Ayush Goel
此外,由于整个功能回退的易用性相同的原因,变基也无法解决问题。 - Ayush Goel
显示剩余2条评论
1个回答

3
是的,你可以使用merge --squash来还原某些提交,即使它已经包含在聚合中。git-revert的工作原理是通过识别在您指定的提交中引入的更改,然后创建一个新的更改来撤消(“还原”)这些更改。
它使用三路合并算法来实现这一点——以要还原的提交作为基础,然后与该提交的祖先和当前提交(HEAD)进行比较。这将隔离仅在该提交中引入的更改。
举个非常牵强的例子,假设你有一个文件,其中包含三个更改(C0C1C2),这些是每个版本的内容:
| C0    | C1    | C2    |
|-------|-------|-------|
| one   | one   | one   |
| two   | 2     | 2     |
| three | three | three |
| four  | four  | FOUR  |

现在,如果您想还原C1,我们将其设置为基础,并将C0C2作为每个侧面以获取更改。在三方合并算法中,您会查看每个侧面与基础的比较。如果所有三行都相等,则将该行不经修改地放入结果中。如果一侧进行了更改,则将更改后的行放入结果中。如果两侧在同一行上进行了更改,则将该行标记为冲突。设置还原操作会给您带来:
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接