【问题标题】:How to stop merging in git?如何停止在git中合并?
【发布时间】:2015-04-09 14:06:45
【问题描述】:

我有一个三向合并分支合并:

git checkout master
git merge BranchA

>> Fast-forward merge

git merge BranchB

>> Three-way-merge (prompts for a merge commit message)

我的问题有两个:

  • 我怎样才能中止合并?通过三向合并,我向编辑器展示了在哪里编写合并提交消息。 但是如果我不保存就退出,git 无论如何都会继续进行合并(只是合并提交消息将是默认消息,而不是我可以编写但中止的消息)

    commit 11111233
        Merge 'BranchB' into master
    

    虽然显然没有确认提交消息,但我希望不会发生合并(与我不确认正常提交消息时的行为相同)

  • 两个合并分支的提交是否会按时间顺序排序? 还是首先(在git log)我会看到来自 BranchA 的提交,然后是来自 BranchB 的提交?

编辑

为了更好地解释第二个问题,我做了一个测试: 从 master 分支开始的 2 个分支(A 和 B)。我在 B 上进行了提交,然后在 A 上,然后再次在 B 上,最后再次在 A 上。 然后我将 BranchA 合并到 master 中。然后将BranchB变成master

但是当我在mastergit log时,这就是结果,也是我问第二个问题的原因:

commit 730fdd4d328999c86fa4d3b6120ac856ecaccab1
Merge: 7eb581b cc1085a
Author: Arthur Conandoyle <Arthur.Conandoyle@live.com>
Date:   Mon Feb 9 21:24:27 2015 +0100

    Merge branch 'BranchB' into master_COPY

commit 7eb581b39a8402e1694cc4bf4eab4a3feb1143f8
Author: Arthur Conandoyle <Arthur.Conandoyle@live.com>
Date:   Mon Feb 9 21:23:18 2015 +0100

    BranchA) - This should be the (second) last change of the branch, and be the
    most recent into the git log, even if I merge another branch into master,
    AFTER the one where we are committing this.

commit cc1085a6aaa2ee4b26d3c3fbb93bee863d9e7c28
Author: Arthur Conandoyle <Arthur.Conandoyle@live.com>
Date:   Mon Feb 9 21:20:29 2015 +0100

    (BranchB) - Add settings to the last new features

commit 5f5b846a2f89886d01244ba77af941f554233b51
Author: Arthur Conandoyle <Arthur.Conandoyle@live.com>
Date:   Mon Feb 9 21:18:54 2015 +0100

    (BranchA) - Add some changes

commit 92a57a56b6b7c9694fbedda71b8070fc58683dde
Author: Arthur Conandoyle <Arthur.Conandoyle@live.com>
Date:   Mon Feb 9 21:18:17 2015 +0100

    (BranchB) - Some changes

commit 221765476e348833cf8da73b1bf5239f3d4240e8
Author: Arthur Conandoyle <Arthur.Conandoyle@live.com>
Date:   Tue Feb 3 12:12:19 2015 +0100

    Change (this is the last commit of the parent 'master' branch)

(正如 Srdjan Grubor 所写)我本来预计首先(按时间顺序)来自合并的 BranchATHEN 所有的提交从合并的 BranchB 提交,按照合并的顺序... .. 但有趣的是,git log 却按时间顺序显示它们,并且提交未按分支分组显示!

【问题讨论】:

  • 尝试写入 empty 消息以中止,即删除所有内容并保存空文件。
  • 很好的建议。这解决了问题(我会说 "bug")并允许中止 merging!
  • 这不是错误。空提交消息中止提交(除非明确允许);对于所有提交都是如此:普通提交和合并提交。如果您使您的正常提交消息模板具有一些初始值,那么退出也不会中止。这是提交的内容,而不是您是否更改了某些内容的事实。否则,只接受默认消息是行不通的。
  • 短语“三路合并”并不是指(无论如何在 git 中)将 两个 其他分支带入您当前的分支。相反,它指的是当将 一个 其他分支引入当前分支时,该过程是通过找到“合并基础”(最近的共同祖先)然后组合两组更改来完成的: -base vs HEAD,合并基础 vs other-branch-tip。在 git 中,当HEAD 是合并基础时会发生“快进”合并。
  • @jthill:在共同祖先是当前HEAD 的情况下,git 仍然会进行双向合并(也称为快进)。因此,至少在read-tree-m 选项的文档中已经提到了这一点。不确定其他人是否还在使用该术语...

标签: git github merge git-commit abort


【解决方案1】:

branchB 合并是完全普通的,要求一个普通的提交消息。有一个默认值,如果您退出而不更改它,则合并将完成。由于合并本身已经成功,现在阻止它的唯一方法是提供一个错误的合并消息(一个空的合并消息会在没有钩子的情况下完成),编辑:或者有一个可以像 vim 的 :cq 那样出错的编辑器,我只是学习了。

当合并停止时,您可以使用 中止它

git merge --abort
# or
git reset --merge

你刚刚犯错的任何事情的退出是

git reset --hard @{1}

git 中没有分支“所有权”的概念,all the ways you can refer to a commit 是同行。

您可以更好地了解git log 向您展示的结构

git log --graph --decorate --oneline

--date-order--topo-order--all 一起尝试。

【讨论】:

  • 改为生成三路合并。两个分支都来自 master,如果第一个 merge 将是 fast-forward,则第二个合并将改为 三个-way-merge 并会要求提交信息;我尝试了两个不同的存储库。您的解决方案是正确的,但我正在寻找一种 abort 的方法,而您建议 undo(我通常使用 git reset @{1},正如您所说) .
  • 关于你的 edit2:我试过 Git 1.7.10.41.9.3 i>,即使您在没有保存的情况下退出编辑器,两者都会确认 合并。要获得正确的行为,您需要提供一个空消息并提交它(正如阿列克谢十在 cmets 中建议的那样);那么它将按预期运行,合并将不完整。仅退出编辑器而不保存是不够的,无论如何都会确认合并,使用默认文本作为 merge 消息。
  • @Kamafeather:jthill 正在谈论 first 合并,这是作为快进完成的。该合并已经完成。写入空提交消息会中止 第二个 合并,但第一个已完成。
  • 为您提供了默认的合并消息。退出而不保存接受该消息并完成合并。编辑:这是故意的,因为默认消息是迄今为止最常见和最好的选择我认为您可能正在使用一种长期被放弃的“三向合并”的感觉。确实,merge 会将两个技巧与原始技巧进行比较,因此涉及三个文件,但人们认为它正在使用中,因为它要好得多。如今,仅计算提示的误导性已减少。
  • @torek: 感谢您的澄清。但是,是的,我没想到第二个 merge 的中止也会撤消第一个。我放置第一个 branch/merge 只是为了举例说明当我尝试合并从与第一个相同的父级开始的第二个分支时发生的情况。 jthill: 感谢您的澄清 :)
【解决方案2】:

关于您的编辑,git log排序它的输出。即使在线性历史中,这也可能令人惊讶。有flags to change the sorting method,添加--graph会将默认排序更改为--topo-order

另外需要注意的是,当 git 对分支进行快进时,并没有合并提交:

      C---D   <-- branch
     /
A---B         <-- mainline

允许mainline 通过快进获取branch 的简单图形结果:

      C---D   <-- mainline, branch
     /
A---B

它被简单地绘制为一条简单的直线,但强制合并提交(使用git merge --no-ff)会产生实际的双父合并提交:

      C---D   <-- branch
     /     \
A---B-------M <-- mainline

which(曾经泛化为有更多提交)为提交排序过程提供了更多有趣的选项。

【讨论】:

  • 感谢您的解释和文档链接。我应该检查一下!我不知道git log 有排序选项,还有默认排序。
【解决方案3】:

完成并使用后,您可以“中止”合并

git reflog

返回到之前的树状态。通常合并不是按时间顺序排序,而是按分支提交顺序排序,然后单独排序。这意味着您将看到您的合并提交,然后是所有源分支提交(按时间顺序),然​​后是您的主分支提交(按时间顺序)。

【讨论】:

  • 你说的和我预期的一样......但我试过了,发现行为不同!......检查EDIT到我的答案顶!
猜你喜欢
  • 1970-01-01
  • 2017-10-18
  • 2019-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 2013-08-05
  • 1970-01-01
相关资源
最近更新 更多