在git中跨分支创建永久不同的更改

时间:2015-01-05 18:13:26

标签: git google-app-engine merge branch

这个问题特别涉及到git和GoogleAppEngine的使用,但它的答案很可能适用于那些拥有分支机构,目的地是针对不同环境的人。

我们发现在合并期间不需要的代码会持续穿过污染分支的问题。

一些背景知识:我们正在使用git来管理上传到GoogleAppEngine的代码。我们有3个主要分支(主,分期和开发),每个分支都有自己独立的GAE项目。部署到GAE的标准方法是通过Gradle插件,该插件使用单个xml配置文件(目录层次结构中的固定名称和固定位置)来指定目标GAE项目和版本号。

e.g。

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <application>projectname-development</application>
    <version>307</version>
    <threadsafe>true</threadsafe>
</appengine-web-app>

因此,此文件已在每个分支上进行了修改,以便为-live标记提供正确的-staging<application>后缀。

我们的工作过程很复杂,但并不罕见。新功能从开发分支并合并回开发(--no-ff,因此我们可以看到分支历史记录)。然后将开发合并到分段中。暂存合并为主。对分段的错误修复分支到错误修复分支,然后合并回到分段并向后合并到开发。

当我们开始在主分支或bugfix与开发分支之间合并时,我们的问题就出现了。 git通过在大多数时间替换XML中的GAE目标项目来解析合并。我可以在第一次合并时理解这一点(因为这是它变得不同的地方),但是我们使用--no-ff和--no-commit执行合并,这样我们就可以正确地更新版本号(因为它们作为一部分递增)我们的合并政策)和git似乎试图在每次使用合并时尝试合并不正确的内容。

&#39; psuedocode&#39;这个问题如下: -

创建初始分支...
1.将xml文件提交给master 2.分公司硕士发展 3.在开发和提交中的xml中更改GAE目标项目

开发一个功能...
4.从开发创建功能分支,制作功能,增加版本号,合并回发展
5.使用--no-ff和--no-commit

将开发合并到master

此时,正如预期的那样,它将GAE目标项目和版本从开发合并到主。我们手动将GAE目标项目更正为主分支上的内容,但将更改保留为版本号;并提交。

开发另一个功能...
6.从开发创建功能分支,制作功能,增加版本号,合并回发展
7.使用--no-ff和--no-commit

将开发合并到master

此时,事情并不像预期的那样。 Git已更改版本号和GAE目标项目。如果不尝试,我99.9%肯定其他源代码控制(根据我的经验,SVN,Vault或Perforce)只会合并版本号,这是我在这里预期的结果。

我们最初没有注意到这个问题,因为SourceTree隐藏了我们的更改(根本没有显示在日志中?!)。只有当从命令行执行此操作并查看沿途的每一步时,我们才会注意到问题的来源。它几乎就像git太聪明了,因为我们没有提交那个大块(因为我们在提交之前手动编辑了文件),我们已经做了某种樱桃选择和它试图在稍后阶段进行延期合并。

所以,我的问题是&#34;我们如何告诉git当我们将合并文件从分支B提交到分支A时,我们已经从中获取了我们想要的所有更改?&#34;,或者对这个问题有更好/不同的解决方案吗?

1 个答案:

答案 0 :(得分:2)

  

它几乎就像git太聪明了,并且它认为因为我们没有提交那个大块(因为我们在提交之前手动编辑了文件)我们已经做了某种樱桃挑选它试图在稍后阶段进行延期合并。

这不可能是真的。 Git只跟踪已提交内容的快照。它并不关心你是如何或为何达到这一点的。

我尝试了你的例子,但是当连续的行发生冲突时,我只有一个问题,即dev中的版本号发生了变化,dev和master之间的应用程序名称不同。在这种情况下,我遇到了冲突,但这是预料之中的,因为Git注意到更改的行不能完全适合目标分支中与原始分支匹配的上下文。

但是,当版本号与应用程序名称分开4行时,我没有问题,只有版本号受到影响,而不是应用程序名称。

无论如何,在程序文件中存储瞬态信息可能不是一个蠢货。最好将版本号和应用程序名称保存在永不提交的属性文件中,然后使用快速脚本更新读取属性文件以将XML文件设置为具有正确的值。更好的是,大多数工具允许您根据属性文件声明变量。尝试调查您的构建工具是否支持该功能。

修改

版本号可能是必需的,但不应在任何分支上提交应用程序名称。相反,使用占位符和结帐挂钩或.gitattributes过滤器,它将使用基于当前分支的相应应用程序名称替换占位符。

有关详细信息,请参阅 http://git-scm.com/book/en/v2/Customizing-Git-Git-Hookshttp://git-scm.com/docs/gitattributes