我有一个相当罕见的源控制问题.在这里的示例中,问题出现在Perforce上,但我怀疑许多SCM会出现同样的问题,尤其是分布式SCM.
Perforce支持更改列表(如果您愿意,还支持更改集).变更列表支持两种常见用法:
提交更改列表时,提交是原子的,以便提交所有文件或不提交任何文件.这是大多数人在提到变更列表时所谈论的标题功能.
Perforce支持多个更改列表.基本上,当您签出文件时,您告诉它它属于哪个更改列表.所以,如果你正在开发一个花哨的新电子邮件功能,它需要花费数月的时间才能完成数百万美元,并且有人从技术支持中找到了一个必须在昨天修复的bug,你不必从头开始整个项目的新分支.您可以将错误文件检入新的更改列表,修复问题,检查新的更改列表并返回新电子邮件功能的实际工作,就好像什么都没发生一样.
在大多数情况下,一切都很好.但是,当您实现电子邮件功能时,您正在整个地方进行数以万计的更改,尤其是在main.h中,并且恰好在开始修复错误时,您会发现您必须进行的微小更改也在main.h. 新功能的更改列表已经检出main.h,因此您无法轻松将其放入更改列表中以进行错误修复.
那你现在怎么办?你有几个选择:
创建一个新的clientspec.Perforce中的clientspec是库中的文件/目录列表,以及要复制所有内容的本地目标.因此,您可以创建项目的第二个副本,而无需对电子邮件功能进行任何更改.
做一个软糖.备份修改后的main.h副本并还原此文件.然后,您可以自由地将main.h签入bugfix更改列表.您修复了该错误,检查错误修正更改列表,然后将main.h签出到电子邮件功能更改列表中.最后,合并您在开始时所做的备份中的所有更改.
您确定您对main.h所做的所有更改都没有副作用或依赖项,因此您只需将main.h移动到bugfix更改列表中,进行更改并将其签入.然后再将其重新检入电子邮件功能更改列表.显然,这种方法存在两个问题:首先,实际上可能存在您未考虑的副作用,其次是您已损坏版本组织.
选项1可能是最干净的,但并不总是实用的.我正在开发的一个项目有数百万行代码和一个非常复杂的构建过程.设置新环境需要一天的时间,因此对于5分钟的错误修复来说实际上并不实际.
选项3是一个糟糕的选择,但它是最快的,所以它可以非常诱人.
这留下了选项2,这是我通常使用的选项.
有人有更好的解决方案吗?
我为这个冗长的问题道歉,但我在StackOverflow上发现,充分考虑问题可以得到更好的答案.
这个确切的问题被称为"纠结的工作副本问题".Ryan Tomayko有一篇名为The Thing About Git的博客文章详细讨论了这个问题以及Git如何解决这个问题.
这是关于Git的最好的事情之一.我git add -p
至少每天使用一次,以帮助提交彼此独立的单个代码块.两个逻辑上不同的更改位于同一源文件中的事实变得无关紧要.