我有2个git分支:
branch1 branch2
我想合并所有的历史(多次提交)的文件。py在branch2到文件。py在branch1,只有该文件。
实际上,我只是想在branch1中的file.py上工作,但想利用merge命令。
最好的方法是什么?
我有2个git分支:
branch1 branch2
我想合并所有的历史(多次提交)的文件。py在branch2到文件。py在branch1,只有该文件。
实际上,我只是想在branch1中的file.py上工作,但想利用merge命令。
最好的方法是什么?
对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
虽然不是合并本身,但有时需要另一个分支上另一个文件的全部内容。Jason Rudolph的博客文章提供了一种将文件从一个分支复制到另一个分支的简单方法。应用如下技巧:
$ git checkout branch1 # ensure in branch1 is checked out and active
$ git checkout branch2 file.py
现在file.py在branch1中。
为了只合并来自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命令特别有用。
其他当前答案实际上都不会“合并”文件,就像您使用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 branch1
git checkout branch2 file.py
git stash
git checkout branch1
git stash pop
我在同样的情况下,我想合并一个文件从一个分支上有许多提交它在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
我所做的有点手动,但我:
正常合并分支;使用revert恢复合并; 检出我所有的文件到HEAD~1,即它们的状态在 合并提交; 重设我的提交隐藏这个黑客从 提交历史。
丑吗?是的。容易记住吗?也没错。
如果您只关心解决冲突,而不关心保存提交历史记录,那么下面的方法应该是有效的。假设你想把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,可以更轻松地解决冲突。
我发现的最不让我头疼的方法是:
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签出源分支的名称和我们想要添加到当前分支的特定文件的路径
git checkout sourceBranchName pathToFile
Matthew Turner的解决方案是最简单的,但是如果branch1和file有相同的名字就会给出一个错误。在这种情况下,将第二行替换为
Git checkout branch2——file.py
如果git checkout——patch branch2 file.py将被接受,那么我应该分享我们还可以使用:
git difftool <branch> [-- <file>]
([]表示可选。)
如果配置为diff.tool,像meld这样的合并工具将允许您使用图形界面手动合并两个文件。
它的一个缺点是,如果某个文件不存在于某个分支中,则无法复制或删除该文件。在这种情况下,我们需要git checkout branch2——file.py。
Git difftool也不保存历史。
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 -
我发现一些答案是有用的,但令人困惑,所以避免任何困惑的未来。我只是想帮助那些有同样困惑的人。
我不会使用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.
我还从参考教程中得到了帮助。
如果有用的话,竖起大拇指。快乐编码:)