我有2个git分支:

branch1 branch2

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

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

最好的方法是什么?


当前回答

我发现的最不让我头疼的方法是:

git checkout <b1>
git checkout -b dummy
git merge <b2>
git checkout <b1>
git checkout dummy <path to file>
git branch -D dummy

这样做之后,b2中文件路径下的文件就是与b1完全合并后的文件。

其他回答

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 -

为了只合并来自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"

当来自branch2的file.py中的内容不再适用于branch1时,它需要选择一些更改并保留其他更改。为了完全控制,使用——patch switch进行交互式合并:

$ 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命令特别有用。

如果您只关心解决冲突,而不关心保存提交历史记录,那么下面的方法应该是有效的。假设你想把a.py b.py从BRANCHA合并到BRANCHB。首先,确保BRANCHB中的任何更改都已提交或隐藏,并且没有未跟踪的文件。然后:

git checkout BRANCHB
git merge BRANCHA
# 'Accept' all changes
git add .
# Clear staging area
git reset HEAD -- .
# Stash only the files you want to keep
git stash push a.py b.py
# Remove all other changes
git add .
git reset --hard
# Now, pull the changes
git stash pop

Git不会识别a.py b.py中存在冲突,但如果确实存在冲突,则会出现合并冲突标记。使用第三方合并工具,如VSCode,可以更轻松地解决冲突。

Matthew Turner的解决方案是最简单的,但是如果branch1和file有相同的名字就会给出一个错误。在这种情况下,将第二行替换为

Git checkout branch2——file.py