【问题标题】:How do I prevent an automerge using Git?如何使用 Git 防止自动合并?
【发布时间】:2011-07-11 05:42:39
【问题描述】:

我正在尝试将本地分支合并到主分支,而无需 Git 进行自动合并。我想“手工挑选”我想合并到 master 中的内容。

当我使用 Git 的 difftool 命令时,我能够比较并选择我想要添加到主分支的内容。但是当我进行合并时,我会丢失我之前选择的内容,因为 Git 会进行自动合并。我可以在合并之前将更改提交到 master,但这样做似乎不自然。

而且 Git 的合并工具仅在合并发生冲突时可用。但是如果 Git 进行自动合并,那么通常不会有冲突,所以我无法运行 mergetool 命令。

更新:

我开始认为我想要完成的事情是不好的做法,或者这是不可能的。也就是说,合并一个主题分支,只让它合并我需要的差异。此外,要让这一点反映在历史中。无论如何,我在试验 Git 时提出的问题浮出水面。

【问题讨论】:

  • 您“预先选择”的这些更改来自哪里?在您进行合并之前,它们是您工作树中的本地修改吗?您是否尝试合并一个分支并只保留其中的一些更改?
  • Jefromi,回答你的第一个问题,它们是从区分主题分支的变化。这是我在第二段第一句中提到的。回答您的第二个问题,是的,它们是本地修改。这就是为什么如果我进行合并(没有先提交)我会丢失那些差异。回答你的第三个问题,是的。我正在尝试合并一个分支,并通过使用差异工具(例如 KDiff3)选择我想要的内容,只保留其中的一些更改。
  • 关于您的更新:如果您打算合并该分支的其余部分,这确实是一种不好的做法。记录合并后,表明您拥有合并提交的内容。不过,您当然可以做您开始做的事情 - 选择性地将几行差异应用到主题分支,然后直接提交(而不是作为合并)。如果您以后合并整个主题,那应该(希望)不会导致冲突。
  • 请在此处接受答案。

标签: git


【解决方案1】:

您正试图绕过 Git 参与合并过程,并手动选择要合并的每个已修改文件的每一行。这与git cherry-pick 不同。 git merge --no-commit 等也不会提供帮助。你需要做:

$ git checkout master
$ git difftool -t kdiff3 local-branch HEAD

KDiff3 窗口中,左侧 (A) 是您的 local-branch,右侧 (B) 是您的当前分支 (master )。

从菜单中选择Merge | Merge Current File(或按具有相同标题的彩色菱形图标)。

然后您将看到每个文件的差异和冲突(如果有)。您将能够选择左侧或右侧(AB),或两者兼而有之,和/或手动调整合并文件。

另一方面,有些事情告诉我您的工作流程存在一些更大的问题。

【讨论】:

  • 选择答案!
  • 如果您已经使用 git config 正确设置了 difftool,则 -t kdiff3 不是必需的或有用的。
  • OP 的工作流程没有任何问题。他可能正面临一个复杂的合并。 Git 喜欢确定某些合并是“安全的”,并在它们根本不安全时静默执行。
  • @FractalSpace 当你遇到合并冲突时,你也在挑选。如果您认为挑选和选择是一个有缺陷的过程,那么它并不比“希望最好”的自动合并更糟糕(甚至可能更好)。
  • @Apprentice Queue 你错过了重点。当 git 确实合并并且没有冲突时,您将无法选择任何东西。 git 神奇地合并文件,这是 op 想要避免的。
【解决方案2】:
git merge --no-commit --no-ff <local-branch>

会的。

当您执行它时,来自local-branch 的更改已应用但尚未暂存。

然后,您可以查看要应用的更改,如果您想全部采用这些更改,请使用

应用它们
git commit -a 

否则,选择要获取的文件,使用git add 暂存它们,最后使用git commit 提交它们。然后使用git checkout -- filename 恢复不需要的文件。

【讨论】:

  • 我尝试了该命令,似乎它执行了自动合并并暂存了文件。运行第一个命令后,我收到以下消息: 自动合并顺利;在按要求提交之前停止
  • @marckassy:但是你可以然后git reset HEADgit add -p 来选择你想要的。
  • 要完全关闭初始合并,请添加-s ours
  • 我想实现同样的目标,在git merge --no-commit --no-ff &lt;local-branch&gt; 之后,我运行了git reset HEAD。这样,所有“为提交而暂存”的更改都变成了“未暂存的”。现在有了git diff,我可以看到完整的差异,我可以addcommit 我想要的并丢弃不需要的更改
【解决方案3】:

如果您不信任自动合并,我可以看到您可能希望这样做,因为文件中不同位置的两次编辑(在不同的分支上完成)可能不会导致自动合并引发冲突,但可能实际上并没有一起工作。

您可能想看看使用自定义合并驱动程序。本页描述了如何去做。

Git - how to force merge conflict and manual merge on selected file

另一种方法是在执行合并之前先找到分支之间不同的文件,然后将文件签出到适当的分支中,以确保您获得干净的合并和包含其中一个或另一个的功能代码两次修改。

git diff --name-only <branch1> <branch2> 
git checkout <branch1> -- <paths>

【讨论】:

  • 这不是不信任 automerge。这是关于它根本没有给我关于 git 对文件做了什么的信息。
  • 我想一种方法是查看另一个分支上的哪些文件不同,然后在合并之前检查每个文件的不同之处另一个分支上的文件不同 git diff --name-only otherbranch 另一个分支中的特定文件有什么不同 git diff -p master someotherbranch -- the_specific_file .txt
  • 当然这是后备。我在说的是 git 给你一条消息“无法推送引用,执行拉取”,然后如果你这样做,它会说“自动合并”(没有关于将要“自动合并”的细节。这是一个可怕的错误信息。
【解决方案4】:

对于 vim 和 vim 逃犯用户:

将以下内容添加到 ~/.gitconfig

[difftool "fugitive"]
  cmd = vimdiff $LOCAL $MERGED $REMOTE
  trustExitCode = false
  keepBackup = false

现在使用 Fugitive 进行 3 路差异

$ git checkout master
$ git difftool -t fugitive somebranch HEAD

关于 $LOCAL、$MERGED、$REMOTE 的注意事项:

$LOCAL 要合并的分支上的文件;向您展示时不受合并过程的影响

$MERGED 部分合并的文件,有冲突;这是合并过程中唯一涉及的文件,实际上,在 meld 中从未向您显示过

$REMOTE 要合并的分支上的文件;向您展示时不受合并过程的影响

【讨论】:

    【解决方案5】:

    我认为你想挑选个人更改:

    git checkout master
    git log --reverse --oneline topic ^master
    

    然后为您希望在主分支中进行的每个提交调用git cherry-pick

    如果应该保留主题分支中的剩余更改,您可能还希望将此分支重新设置在新 master 之上:

    git rebase master topic
    

    【讨论】:

    • 有趣的是,我从来不知道cherry-pick 命令。我希望使用差异工具(例如KDiff3)从提交中手动选择几行代码。似乎这合并了整个提交。
    • @marckassy:如果您使用git cherry-pick --no-commit; git reset HEAD,那么您可以使用git add -p 仅展示您想要的内容。
    猜你喜欢
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-28
    相关资源
    最近更新 更多