【问题标题】:Is there a way to cleanly and easily undo a git merge?有没有办法干净轻松地撤消 git 合并?
【发布时间】:2021-02-24 01:01:26
【问题描述】:

我读过 git reset commitBeforeDoingMerge --hard 不会撤消合并:

1pm-3pm This is my branch and I need to merge master into it
1pm-2pm This was master
1pm-2pm-3pm-4pm Merging ended up doing this, 4pm being the merge commit
1pm-2pm-3pm if This is the result if you do git reset 3pm --hard, because it does not undo the merge, it just goes back to that commit in the branch that was merged.

现在,另一个建议是做 git revert 4pm -m 1,但是根据manual 有问题:

通常您无法还原合并,因为您不知道哪一边 的合并应该被认为是主线。该选项指定 主线的父编号(从 1 开始)并允许还原 反转相对于指定父级的更改。

还原合并提交声明您永远不会想要树 合并带来的变化。结果,以后的合并只会 引入由非祖先的提交引入的树更改 先前还原的合并。这可能是也可能不是您想要的。

那么,有没有办法干净而轻松地撤消 git 合并?

【问题讨论】:

  • git reset --hard 将撤消合并。 (总是干净利落)但我认为你应该澄清你是如何得到“合并”的,因为合并应该至少有两个平行的分支而不是你的单行。
  • @ian 我更新了问题,也许现在更清楚了。 Git reset --hard 会将您带到该快照,但不会撤消对历史记录所做的更改。

标签: git git-merge git-reset git-revert


【解决方案1】:

重置应该有效,但在 master 上,重置为 e:

合并后:

a-b-d  (mybranch)
  \
   c-e (master)

myBranch 到 master 的合并应该给出:

a-b---d  (mybranch)
  \    \
   c-e-f (master)

没有分支会列出 abcdef,只有 abcef (master)

如果您在masterreset --hard e,您将返回原始历史记录(上面的第一个)

如果您在 master 上 reset --hard d,则您已移动 master HEAD 但合并仍然存在:

a-b---d  (mybranch, master)
  \    \
   c-e-f

【讨论】:

  • 我正在将 master 合并到我的分支中。我不明白你的答案,所以我更新了这个问题,也许它更清楚了。
【解决方案2】:

我读过 git reset commitBeforeDoingMerge --hard 不会撤消合并

无论你在哪里读到,都是错误的。这正是撤消合并的方法。

假设您将branch 合并到master。所以我们在合并之前有这个:

A -- B -- C (master)
 \
  X -- Y (branch)

好的,所以我们 git checkout mastergit merge branch。结果是:

A -- B -- C -- D (master)
 \             |
  X -- Y (branch)

...其中 D 是合并提交,C 和 Y 作为其父项。

如果你现在说git reset --hard <SHA-of-C>,你又回到了这个:

A -- B -- C (master)
 \
  X -- Y (branch)

这是一个完美的撤消。

【讨论】:

    【解决方案3】:

    我仍然不确定你在做什么,但这不是git merge 的工作方式。我会尝试重现你所做的,也许你能发现其中的不同。

    首先我创建了你的两个起始分支:

    git log --oneline --graph --all
    * 0593ba1 (HEAD -> test) 3pm
    | * eba415c (master) 2pm
    |/
    * 7f9a804 1pm
    

    将 master 合并到测试中。 git merge master -m "4pm"

    git log --oneline --graph --all
    *   6be609f (HEAD -> test) 4pm
    |\
    | * eba415c (master) 2pm
    * | 0593ba1 3pm
    |/
    * 7f9a804 1pm
    

    现在我们将测试重新设置为下午 3 点

    git reset --hard 0593ba1
    HEAD is now at 0593ba1 3pm
    
    git log --oneline --graph --all
    * 0593ba1 (HEAD -> test) 3pm
    | * eba415c (master) 2pm
    |/
    * 7f9a804 1pm
    

    现在我们看到 2pm commit 只在 master 中,确认一下 only test 的日志

    git log --oneline
    0593ba1 (HEAD -> test) 3pm
    7f9a804 1pm
    

    这就是我合并和撤消合并的方式,请随时告诉我你在做什么不同的地方,或者我没有重新创建你的例子,比如你需要它。

    【讨论】:

    • 我认为当我在脑海中混合撤消被推送的合并时,我感到困惑。所以我试图找到一种干净的方法来撤销它而不重写历史。
    • 不用担心,很高兴为您提供帮助。如果您真的想在不重写历史记录的情况下撤消合并,您可以使用git revert -m <#parent> <sha> 来完成,但请注意阅读此内容,因为它有自己的pitfalls,我不确定这是一个更好的重写解决方案历史。
    猜你喜欢
    • 1970-01-01
    • 2020-06-10
    • 2016-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多