16.3 合并二:逻辑冲突

自动合并如果成功地执行,则大多数情况下就意味着完事大吉,但是在某些特殊情况下,合并后的结果虽然在Git看来是完美的合并,实际上却存在着逻辑冲突。

一个典型的逻辑冲突是一个用户修改了一个文件的文件名,而另外的用户在其他文件中引用旧的文件名,这样的合并虽然能够成功但是包含着逻辑冲突。例如:

(1)一个C语言的项目中存在头文件hello.h,该头文件定义了一些函数声明。

(2)用户user1将hello.h文件改名为api.h。

(3)用户user2写了一个新的源码文件foo.c并在该文件中包含了hello.h文件。

(4)两个用户的提交合并后,会因为源码文件foo.c找不到所包含的文件hello.h而导致项目编译失败。

再举一个逻辑冲突的示例。假如一个用户修改了函数返回值而另外的用户使用旧的函数返回值,虽然成功合并但是存在逻辑冲突:

(1)函数compare(obj1,obj2)用于比较两个对象obj1和obj2。返回1代表比较的两个对象相同,返回0代表比较的两个对象不同。

(2)用户user1修改了该函数的返回值,返回0代表两个对象相同,返回1代表obj1大于obj2,返回-1则代表obj1小于obj2。

(3)用户user2不知道user1对该函数的改动,仍以该函数原返回值判断两个对象的异同。

(4)两个用户的提交合并后,不会出现编译错误,但是软件中会潜藏着重大的Bug。

上面的两个逻辑冲突的示例,尤其是最后一个非常难以捕捉。如果因此而贬低Git的自动合并,或者对每次自动合并的结果疑神疑鬼,进而花费大量精力去分析合并的结果,则是因噎废食、得不偿失。一个好的项目实践是每个开发人员都为自己的代码编写可运行的单元测试,项目每次编译时都要执行自动化测试,捕捉潜藏的Bug。在2010年OpenParty上的一个报告中,我介绍了如何在项目中引入单元测试及自动化集成,可以参考下面的链接:

http://www.beijing-open-party.org/topic/9

http://wenku.baidu.com/view/63bf7d160b4e767f5acfcef6.html