如何合并来自Git分支的特定文件

我有2个git分支branch1和branch2,我想将branch2中的file.py合并到branch1中的file.py中,只有这个文件。

实质上,我只是想在branch1中的file.py上工作,但是想要利用merge命令。 做这个的最好方式是什么?

接受的答案已经提到使用git checkout 。 现在, branch2中的file.py内容可能不再适用于branch1 。 这种情况将需要采取一些变化,并留下其他人。 因此,要完全控制使用--patch开关进行交互式合并:

 $ git checkout --patch branch2 file.py 

git-add(1)手册页中的交互模式部分解释了要使用的密钥:

 y - stage this hunk n - do not stage this hunk q - quit; do not stage this hunk nor any of the remaining ones a - stage this hunk and all later hunks in the file d - do not stage this hunk nor any of the later hunks in the file g - select a hunk to go to / - search for a hunk matching the given regex j - leave this hunk undecided, see next undecided hunk J - leave this hunk undecided, see next hunk k - leave this hunk undecided, see previous undecided hunk K - leave this hunk undecided, see previous hunk s - split the current hunk into smaller hunks e - manually edit the current hunk ? - print help 

split命令特别有用。

正如在评论中指出的,这在技术上不是“合并”,这就是为什么下面的链接使用引号。 但是,我很less需要像其他海报所描述的那样复杂的东西,所以我认为这对于OP的问题是非常有用的,如果不是一个合适的解决scheme的话。

看看这个页面: Git提示:如何从另一个分支“合并”特定的文件它提供了最简单的方法来做到这一点,恕我直言。

基本上,适用于您的情况:

 $ git checkout branch1 # ie make sure you're in branch1 $ git checkout branch2 file.py 

很容易,file.py现在在branch1。

是否对branch2中的file.py进行了自己的提交修改,而不是修改其他文件? 如果是这样,你可以简单地cherry-pick修改:

 git checkout branch1 git cherry-pick <commit-with-changes-to-file.py> 

否则, merge不会在单个path上运行…您可能只需创build一个来自branch2git diff修补程序file.py ,然后git apply它们git applybranch1

 git checkout branch2 git diff <base-commit-before-changes-to-file.py> -- file.py > my.patch git checkout branch1 git apply my.patch 

其他当前的答案都不会真正“合并”文件,就像使用合并命令一样。 (至多他们会要求你手动select差异。)如果你真的想利用来自共同祖先的信息进行合并,你可以按照git的“高级合并”部分中find的步骤进行操作参考手册。

对于这个协议,我假设你想合并来自origin / master的文件“path / to / file.txt”到HEAD中 – 根据需要进行修改。 (您不必在存储库的顶部目录中,但它有帮助。)

 # Find the merge base SHA1 (the common ancestor) for the two commits: git merge-base HEAD origin/master # Get the contents of the files at each stage git show <merge-base SHA1>:path/to/file.txt > ./file.common.txt git show HEAD:path/to/file.txt > ./file.ours.txt git show origin/master:path/to/file.txt > ./file.theirs.txt # You can pre-edit any of the files (eg run a formatter on it), if you want. # Merge the files git merge-file -p ./file.ours.txt ./file.common.txt ./file.theirs.txt > ./file.merged.txt # Resolve merge conflicts in ./file.merged.txt # Copy the merged version to the destination # Clean up the intermediate files 

git merge-file应该使用所有的默认合并设置进行格式化等。

另外请注意,如果您的“我们的”是工作拷贝版本,并且您不想过于谨慎,则可以直接在文件上操作:

 git merge-base HEAD origin/master git show <merge-base SHA1>:path/to/file.txt > ./file.common.txt git show origin/master:path/to/file.txt > ./file.theirs.txt git merge-file path/to/file.txt ./file.common.txt ./file.theirs.txt 

要仅合并来自file.pyfile.py的更改,请使其他更改消失。

 git checkout -B wip branch2 git read-tree branch1 git checkout branch2 file.py git commit -m'merging only file.py history from branch2 into branch1' git checkout branch1 git merge wip 

合并将永远不会看任何其他文件。 如果树木足够不同,您可能需要“-f”结帐。

请注意,这将使branch1看起来好像branch2的历史logging中的所有内容都被合并了,这可能不是你想要的。 上面第一个结帐的更好的版本可能是

 git checkout -B wip `git merge-base branch1 branch2` 

在这种情况下,提交消息可能也应该是

 git commit -m"merging only $(git rev-parse branch2):file.py into branch1" 

你可以stashstash pop文件:

 git checkout branch1 git checkout branch2 file.py git stash git checkout branch1 git stash pop