我有2个git分支:

branch1 branch2

我想合并所有的历史(多次提交)的文件。py在branch2到文件。py在branch1,只有该文件。

实际上,我只是想在branch1中的file.py上工作,但想利用merge命令。

最好的方法是什么?


当前回答

其他当前答案实际上都不会“合并”文件,就像您使用merge命令一样。(在最好的情况下,他们会要求你手动选择差异。)如果你真的想利用来自公共祖先的信息进行合并,你可以遵循一个基于git参考手册“高级合并”部分的过程。

对于这个协议,我假设你想要将文件“path/to/file.txt”从origin/master合并到HEAD - modify中。(你不必在你的存储库的顶部目录,但这是有帮助的。)

# 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 (e.g. 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的合并文件应该使用所有默认的合并设置来格式化等等。

还要注意,如果你的“ours”是工作副本版本,你不想过于谨慎,你可以直接对文件进行操作:

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

其他回答

Git checkout为此提供了一个——merge选项

Git checkout -merge branch2 file.py

使用此选项,将重新创建有冲突的合并。

否则,当一个新的合并发生时:

# Detach and overwrite file.py with content from branch2 
git checkout --detach
git checkout branch2 file.py

# Amend changes and switch back
git commit --amend --no-edit
git checkout -

# Merge the detached branch back in
git merge --no-commit -

你可以隐藏和隐藏弹出文件:

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

对branch2中的file.py的所有修改是否都在各自的提交中,与对其他文件的修改分开?如果是这样,你可以简单地选择更改:

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

否则,merge不会在单独的路径上操作…你也可以从branch2中创建一个file.py更改的git diff补丁,然后git将它们应用到branch1:

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

为了只合并来自branch2的file.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

Merge甚至不会查看任何其他文件。如果树的差异足够大,您可能需要'-f'签出。

注意,这将使branch1看起来好像branch2历史中的所有内容都已合并,这可能不是您想要的。上面第一次签出的一个更好的版本可能是

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

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

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

其他当前答案实际上都不会“合并”文件,就像您使用merge命令一样。(在最好的情况下,他们会要求你手动选择差异。)如果你真的想利用来自公共祖先的信息进行合并,你可以遵循一个基于git参考手册“高级合并”部分的过程。

对于这个协议,我假设你想要将文件“path/to/file.txt”从origin/master合并到HEAD - modify中。(你不必在你的存储库的顶部目录,但这是有帮助的。)

# 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 (e.g. 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的合并文件应该使用所有默认的合并设置来格式化等等。

还要注意,如果你的“ours”是工作副本版本,你不想过于谨慎,你可以直接对文件进行操作:

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