还有一个文件,比如说
fileA
,我们想要在这两个分支上保留不同的版本。但每次我们都要将 'release' 合并到 'master',我们该如何做才能使 'master' 中的
fileA
不会被分支 'release' 中的 fileA
覆盖?fileA
,我们想要在这两个分支上保留不同的版本。fileA
不会被分支 'release' 中的 fileA
覆盖?Pro Git在8.2自定义Git——Git属性的“合并策略”部分描述了如何实现这种效果。
应用到你的情况中,首先创建Merge Strategies
You can also use Git attributes to tell Git to use different merge strategies for specific files in your project. One very useful option is to tell Git to not try to merge specific files when they have conflicts, but rather to use your side of the merge over someone else’s.
This is helpful if a branch in your project has diverged or is specialized, but you want to be able to merge changes back in from it, and you want to ignore certain files. Say you have a database settings file called
database.xml
that is different in two branches, and you want to merge in your other branch without messing up the database file. You can set up an attribute like this:
database.xml merge=ours
And then define a dummy
ours
merge strategy with:$ git config --global merge.ours.driver true
If you merge in the other branch, instead of having merge conflicts with the
database.xml
file, you see something like this:$ git merge topic Auto-merging database.xml Merge made by recursive.
In this case,
database.xml
stays at whatever version you originally had.
fileA
。$ echo 'master fileA' > fileA
$ git add fileA ; git commit -m "master fileA"
[master (root-commit) fba9f1a] master fileA
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 fileA
使它特殊。
$ echo fileA merge=ours > .gitattributes
$ git add .gitattributes ; git commit -m 'fileA merge=ours'
[master 98e056f] fileA merge=ours
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 .gitattributes
$ git config --global merge.ours.driver true
release
分支。$ git checkout -b release
Switched to a new branch 'release'
$ echo 'release fileA' > fileA
$ git add fileA ; git commit -m 'release fileA'
[release 53f3564] release fileA
1 files changed, 1 insertions(+), 1 deletions(-)
目前还没有发生什么特别的事情:版本控制只是按照预期工作。
现在,我们将功能B实现到master
上。
$ git checkout master
Switched to branch 'master'
$ touch featureB ; echo 'With Feature B' >> fileA
$ git add featureB fileA ; git commit -m 'Feature B'
[master 443030f] Feature B
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 featureB
请保持冷静。
这里是我们特殊的合并驱动器发挥作用的地方。我们的英雄想要将来自master
的新代码合并到release
中。首先切换分支。
$ git checkout release
Switched to branch 'release'
验证一下fileA
是否包含我们期望的内容。
$ cat fileA
release fileA
master
。$ git merge master
Auto-merging fileA
Merge made by recursive.
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 featureB
行 Auto-merging fileA
是一种特殊情况的暗示。确切地说:
$ cat fileA
release fileA
gitattributes文档中的“定义自定义合并驱动程序”部分解释了。
merge.*.driver
变量的值用于构建一个命令,以合并祖先版本(%O
)、当前版本(%A
)和其他分支版本(%B
)。当构建命令行时,这三个标记将被替换为保存这些版本内容的临时文件的名称...期望合并驱动程序通过覆盖名为
%A
的文件来保留合并结果,并在成功合并时退出零状态或在存在冲突时退出非零状态。
自定义ours
驱动程序几乎不使用此机制,只使用true
命令以退出零状态。这样做可以达到所需的效果,因为它从我们当前所在的任何分支的fileA
开始 - 这是我们想要的结果 - 然后在合并覆盖阶段(即,忽略由%B
指定的其他分支版本),最后告诉git一切都很好,成功退出状态。