Git - 两个分支上具有不同版本的相同文件, merge 时不想覆盖

标签 git branching-and-merging multiple-versions

我们有两个分支 -- 'master' 和 'release'

我们有一个文件,比如fileA,我们想在这两个分支上保持不同的版本。

但是每次,我们都要将'release' merge 到'master'中,我们如何实现,'master'中的fileA不会被fileA覆盖> 在分支“发布”中。

最佳答案

Pro Git“Merge Strategies” 中描述了如何获得这种效果节8.2 Customizing Git — Git Attributes .

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(-)

目前还没有发生什么特别的事情:版本控制只是在此时按照预期的方式工作。

现在,我们在 master 上实现功能 B

$ 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

尽量克制自己的兴奋。

这是我们特殊的 merge 驱动程序发挥作用的地方。我们的主人公想要将来自 master 的新代码 merge 到 release 中。先切换分支。

$ git checkout release
Switched to branch 'release'

完整性检查 fileA 是否包含我们期望的内容。

$ cat fileA
release fileA

master merge Feature B

$ 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

工作原理

本节“Defining a custom merge driver”gitattributes documentation解释。

The merge.*.driver variable’s value is used to construct a command to run to merge ancestor’s version (%O), current version (%A) and the other branches' version (%B). These three tokens are replaced with the names of temporary files that hold the contents of these versions when the command line is built …

The merge driver is expected to leave the result of the merge in the file named with %A by overwriting it, and exit with zero status if it managed to merge them cleanly, or non-zero if there were conflicts.

定制的我们的 驱动程序几乎没有使用这些机制,只使用了true command。以零状态退出。这达到了预期的效果,因为它从我们当前所在的任何分支的 fileA 开始——这是我们想要的结果——然后在 merge 覆盖阶段什么都不做(, 忽略由 %B) 命名的另一个分支的版本),最后告诉 git 一切都很好,退出状态是成功的。

关于Git - 两个分支上具有不同版本的相同文件, merge 时不想覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28691602/

相关文章:

git - 如何在 Git 中 check out 一个文件的特定版本?

git - Jenkins 中的 hudson.util.HudsonFailedToLoad 错误

git rev-parse --verify 说 "fatal: Needed a single revision"

java - 运行多个 Java 版本

GIT 从 "git describe"的输出中 check out 代码

Mercurial:关于在分支之间 merge 时如何跳过某些变更集的任何想法?

svn - cherrypick svn merge branch to trunk,随后与 --reintegrate 合并?

Mercurial将默认 merge 到命名分支

android - 维护多个市场的 Android 应用程序(在 Git 上)

Python wave 模块仅适用于 v2.7,不适用于 v3.4 linux