如何在git中合并特定文件并手动解决差异?

时间:2017-06-07 23:56:35

标签: git merge

使用git,我如何执行特定文件的手动合并?当我说&#34;手动合并&#34;我的意思是让git插入<<<<HEAD=====等行并要求我做出选择(如果这个术语不是&#34;手动合并&#34;请指教我。 )。

我读了这个Q&A,所以我知道git checkout <branch> <file> <file> ...让我从我想要的源分支中提取文件;但有没有办法手动解决所有差异?

尝试合并来自多个来源的信息,我尝试git merge --no-commit source_branch ../file.c,但git的回复是merge: ../file.c - not something we can merge

2 个答案:

答案 0 :(得分:1)

git merge命令处理提交(句点,句号,结尾选项......好吧,有一些选项,但它们仍然适用于提交范围的合并)。它:

  • 以当前(HEAD)提交开始;
  • 需要指定其他提交,通常是分支名称;
  • 使用git merge-base --all HEAD other-commit;
  • 自动查找合并基础提交
  • 和(假设单个合并基础)合并由两个差异产生的所有文件:diff -M base HEADdiff -M base other

因此,除非这两个提交范围git diff命令中的一个或两个只选择一个已更改的文件,否则不能使用git merge来执行此操作。

与第二个文件相比, 可以使用git checkout -p对一个文件执行交互式修补程序。这不是合并,虽然有些人将此称为&#34;双向合并&#34;操作

所以,可能的解决方案

您还可以使用git checkoutgit show从特定提交中提取单个文件的特定版本。如果您选择三个这样的版本 - 例如合并库,当前提交和其他一些提交 - 您可以使用git merge-file命令指示Git对该文件执行三向合并。例如:

git show 1234567:foo.txt > /tmp/foo.txt.base
cp foo.txt /tmp/foo.txt.merge
git show 8888888:foo.txt > /tmp/foo.txt.other

(cd /tmp; git merge-file foo.txt.merge foo.txt.base foo.txt.other)

您现在在/tmp/foo.txt.merge中有一个合并文件,包含任何冲突标记。请注意,此文件独立于Git存储库,但如果您喜欢,则可以使用它替换工作树中的任何文件(例如foo.txt)。或者,当然,您甚至可以直接在工作树中执行合并文件操作。

如果将第一个硬编码的提交哈希替换为其他分支名称,并将中间(合并基础)提交哈希替换为git merge-base --all HEAD otherbranch生成的哈希,则可能会得到您想要的那种东西。 / p>

可能更容易的选择

您还可以运行git merge -n来运行完全合并(所有文件中的所有文件,自动查找合并基本提交),但避免提交生成的合并,即使Git似乎都有效。然后,您只能完成您关心的合并部分,保存结果,运行git merge --abort以终止正在进行的合并,并将保存的结果复制回来。

答案 1 :(得分:0)

我已经取消了我想要的东西:

>git checkout source_branch ../file.c
>git reset HEAD ../file.c
Unstaged changes after reset:
M       utils/file.c
>git add -p ../file.c

以上介绍了交互式的hunk编辑器。

我想这有点好,但还有更好的答案吗?即一个插入<<<<HEAD=====等行,并且需要我的手动解决方案是基于每个文件而不是按照我的解决方案所需的每个块的方式解决?