有没有办法干净轻松地撤消 git 合并?
Posted
技术标签:
【中文标题】有没有办法干净轻松地撤消 git 合并?【英文标题】:Is there a way to cleanly and easily undo a git merge? 【发布时间】: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 会将您带到该快照,但不会撤消对历史记录所做的更改。
【参考方案1】:
重置应该有效,但在 master 上,重置为 e:
合并后:
a-b-d (mybranch)
\
c-e (master)
从myBranch
到 master 的合并应该给出:
a-b---d (mybranch)
\ \
c-e-f (master)
没有分支会列出 abcdef,只有 abcef (master)
如果您在master
上reset --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 master
和 git 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,我不确定这是一个更好的重写解决方案历史。以上是关于有没有办法干净轻松地撤消 git 合并?的主要内容,如果未能解决你的问题,请参考以下文章
text 边框的速记属性干净整洁,但是使用此边框SCSS Mixin,您可以轻松地向一侧添加边框或
优雅的使用git搭建项目环境教程--轻松拉取合并protected的分支