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


Answers:


206

file.py来自branch2的内容不再适用于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命令特别有用。


3
我们如何使用补丁同时使用合并工具?而不是关键内容
Gabriel

@Gabriel我什至在补丁文件和tarball中都使用了Git,因为创建回购代码(git init <dir>)并最终将其丢弃(rm -r <dir>)非常容易。
pdp

105

尽管本质上不是合并,但有时需要另一个分支上另一个文件的全部内容。Jason Rudolph的博客文章提供了一种将文件从一个分支复制到另一个分支的简单方法。应用如下技术:

$ git checkout branch1 # ensure in branch1 is checked out and active
$ git checkout branch2 file.py

现在file.pybranch1中


90
容易,但这实际上不是合并。它只是覆盖file.py与无论是在分支2
格雷格Hewgill

如果将文件从branch1合并回branch2怎么办?你会发生冲突!
阿米尔(Amir)

这是否保留提交历史记录?
C2H50H

18

当前没有其他答案可以像实际使用合并命令一样“合并”文件。(充其量,它们会要求您手动选择差异。)如果您实际上想利用来自共同祖先的信息进行合并,则可以按照git 的“高级合并”部分中的步骤进行操作。参考手册。

对于此协议,我假设您要将文件“ 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 (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 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

15

是否所有的修改file.pybranch2自己提交,从修改到其他文件分开?如果是这样,您可以简单地cherry-pick更改:

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

否则,merge不工作在各个路径......你还不如干脆创建一个git diff补丁file.py从变化branch2以及git apply它们branch1

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

8

您可以stashstash pop文件:

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

这将用branch2 / file.py的内容覆盖branch1 / file.py,而不是应引起合并冲突来解决的合并。
plumSemPy

2

要仅合并来自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

合并甚至不会查看任何其他文件。如果树足够不同,则可能需要“ -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"

0

我在同样的情况下,我想合并一个分支上的文件,该分支在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

0

我所做的是一些手动的,但是我:

  1. 正常合并分支机构;恢复与的合并revert
  2. 将我的所有文件检出到HEAD~1,即它们在合并提交中的状态;
  3. 重新确定我的提交,以从提交历史记录中隐藏此黑客。

丑陋?是。容易记住?也可以

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.