我有2个git分支:

branch1 branch2

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

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

最好的方法是什么?


当前回答

我发现一些答案是有用的,但令人困惑,所以避免任何困惑的未来。我只是想帮助那些有同样困惑的人。

我不会使用branch1和branch2的名称,而是master(活动代码)和hotfix/abc(从master提取)和一个测试分支。

现在,我想将一些特定的文件从测试合并到hotfix/abc,因为不建议从测试或登台分支直接在master上合并。要做到这一点,我将做以下工作:

git checkout hotfix/abc git checkout --merge testing path/to/file1.php path/to/file2.js git add . git commit -m "Fixed specific issue" git push Now go to repo and make a pull request for hotfix/abc to master branch. If you don't know how to do that here I've a small tutorial on that. And if you generally want to learn how these branches and git work, I'd recommend you to watch this <= twenty minutes playlist. Now review your pull request with master and merge it. In case you see any conflicts, it's time to merge master into hotfix/abc. And resolve conflicts over there. And then again repeat step 3-5 followed by 7.

我还从参考教程中得到了帮助。

如果有用的话,竖起大拇指。快乐编码:)

其他回答

我在同样的情况下,我想合并一个文件从一个分支上有许多提交它在2个分支。我尝试了上面提到的很多方法和我在网上找到的其他方法,都失败了(因为提交历史很复杂),所以我决定用我的方式(疯狂的方式)。

git merge <other-branch>
cp file-to-merge file-to-merge.example
git reset --hard HEAD (or HEAD^1 if no conflicts happen)
cp file-to-merge.example file-to-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

我所做的有点手动,但我:

正常合并分支;使用revert恢复合并; 检出我所有的文件到HEAD~1,即它们的状态在 合并提交; 重设我的提交隐藏这个黑客从 提交历史。

丑吗?是的。容易记住吗?也没错。

当来自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,可以更轻松地解决冲突。