工欲善其事,必先利其器。
前一阵子,公司的版本控制从svn
迁移到了git
,不得不说,git
确实比svn
要强大好多,单单是一个分支功能,就有很多值得学习的地方,通过git
分支的版本控制,我们可以很方便的进行不同开发环境的切换。
先讲一下,我们为什么要做开发与正式环境的分离。以前使用svn
的时候,我们没有分环境之说,这会导致一个问题,那就是我们的开发版无法与线上的版本并存,如果你想要对照功能的话,就必须要删掉另一个,因为二者的BundleID
是一样的。现在我们的APP通过git的版本控制分成了三个分支,对应着三个环境,分别是publish(正式环境)
,simulate(仿真环境,接近正式环境)
,和develop(开发环境)
,每一个环境都对应着不同的info.plist
配置文件,它们各自的BundleID
是不同的,因此可以理解为三个软件,这样我们在切换分支的时候,就会进入不同的开发环境,方便很多,打包后也可以在手机上并存。
现在来看,分支切换是没有什么问题的,然而在分支进行合并的时候,plist配置文件势必会发生被覆盖的情况,比如我从publish
正式环境分出来一个功能分支func1
进行相关功能的开发,开发完后,我需要先合并到develop
上进行测试,于是我切换到develop
分支,将我的功能分支func1
合并过去,合并完后,会发现我的develop
分支的配置文件,变成了publish
的配置文件,于是我需要再手动的将这些变化改过来,这很明显不是我们想要的结果,在讲究时间成本的开发环境下,这样做无异于浪费。
如何在分支合并的时候,忽略掉一些指定的文件不让它们发生合并呢。
网上搜了一下,发现也有很多前辈遇到类似的问题,比如这篇文章,大致的做法就是通过gitattribute
方法:
- 在你的工程目录下创建
.gitattribute
文件,然后在其中写入你想要忽略掉的文件,格式如下:
info.plist merge = ours
xxx.h merge = ours
//有多个的话,依次排列即可
- 执行
git config merge.ours.driver true
即可。
网上的很多文章到此就为止了,然而这样并不够。
由于开发的时候,功能分支一定都是从publish
分支出来,并且只存在publish
分支(包括功能分支)合并到develop
和simuluate
分支的情况,因此我们只需要保证publish
分支(包括功能分支)向别的分支合并时,别的分支的配置文件不会覆盖掉就可以了。
现在如果我们在publish
分支下创建了gitattribute
文件,并在里面按照上面的方法对info.plist
文件进行合并忽略设置。然后我们从publish
环境分出develop
与simulute
分支,并对dev
与sim
分支的plist
文件进行修改,此时我们将publish
分出来的功能分支func1
往另外两个分支合并的时候没有问题,不会发生覆盖。可是当我们改变了publish
分支下info.plist
文件的任何一处后,再将publish
(包括从其中分出来的功能分支)合并到别的分支的时候,info.plist
文件又会被覆盖掉。这个方法貌似就失效了。
困惑了很久后,最终在stackoverflow和同事的帮助下,找到了答案,发现这真是一个隐藏的坑,原来gitattribute
方法生效是有条件的,跟文件的修改顺序有关系,只有先修改的往后来修改的合并的时候才会生效。这里的先后是指文件的最后修改时间,不是创建的时间,如果最近修改过,那它就是最新的,比如刚才的例子,我们修改了publish
分支的info.plist
,而没有对另外两个分支下的info.plist
进行修改,那么publish
分支下的info.plist
就比另外两个分支新,这时候合并的时候,gitattribute
就会失去作用,那么该如做呢,我们在修改完publish
分支后,需要再次修改另外两个分支下的plist
配置文件,即使没啥可以改的,也要改(可以先改错,再改回去)这样我们publish
分支下的,就会仍然保持最旧。
方法比较繁琐,但确实有效。