Version control 在源代码管理系统中处理多个变更集

Version control 在源代码管理系统中处理多个变更集,version-control,perforce,Version Control,Perforce,我很少遇到源代码管理方面的问题。在这里的示例中,Perforce出现了问题,但我怀疑许多scm也会出现同样的问题,尤其是分布式scm Perforce支持变更列表(或变更集,如果您愿意)。变更列表支持两种常见用法: 当您提交变更列表时,提交是原子的,因此所有文件都提交或没有提交。这是大多数人在提到变更列表时谈论的标题特性 Perforce支持多个变更列表。基本上,当您签出一个文件时,您会告诉它它属于哪个变更列表。因此,如果你正在开发一个花哨的新电子邮件功能,它将花费数月的时间,赚数百万美元,而且

我很少遇到源代码管理方面的问题。在这里的示例中,Perforce出现了问题,但我怀疑许多scm也会出现同样的问题,尤其是分布式scm

Perforce支持变更列表(或变更集,如果您愿意)。变更列表支持两种常见用法:

  • 当您提交变更列表时,提交是原子的,因此所有文件都提交或没有提交。这是大多数人在提到变更列表时谈论的标题特性

  • Perforce支持多个变更列表。基本上,当您签出一个文件时,您会告诉它它属于哪个变更列表。因此,如果你正在开发一个花哨的新电子邮件功能,它将花费数月的时间,赚数百万美元,而且技术支持部门的某个人向你提出了一个必须在昨天修复的错误,那么你不必从整个项目的新分支开始。您可以将错误文件签出到新的变更列表中,修复问题,签入新的变更列表,然后重新开始新电子邮件功能的实际工作,就好像什么都没有发生一样

  • 在大多数情况下,一切都很好。然而,当你实现电子邮件功能时,你在各地都做了无数的更改,尤其是在main.h中,而当你着手修复bug时,你会发现你必须做的微小更改也在main.h中。新功能的变更列表已签出main.h,因此您无法轻松将其放入变更列表中进行bug修复

    现在你做什么?您有几个选择:

  • 创建一个新的clientspec。Perforce中的clientspec是仓库中的文件/目录列表,是复制所有内容的本地目的地。因此,您可以创建项目的第二个副本,而无需对电子邮件功能进行任何更改

  • 做一个软糖。备份main.h的修改副本并还原此文件。然后,您可以自由地将main.h签出到错误修复更改列表中。修复错误,签入错误修复变更列表,然后将main.h签出到电子邮件功能变更列表中。最后,合并从一开始所做备份中进行的所有更改

  • 您确定对main.h所做的所有更改都没有副作用或依赖项,因此只需将main.h移动到bugfix更改列表中,进行更改并签入即可。然后再次将其签出到电子邮件功能更改列表中。显然,这种方法存在两个问题:第一,实际上可能存在您没有考虑的副作用,第二,您破坏了您的版本历史

  • 选项1可能是最干净的,但并不总是实用的。我正在做的一个项目有数百万行代码和一个非常复杂的构建过程。安装一个新环境需要一天的时间,所以5分钟的bug修复是不实际的

    选项3是一个坏选项,但它是最快的,所以它可能非常诱人

    剩下的选项2就是我通常使用的选项

    有谁有更好的解决办法吗


    对于这个冗长的问题,我深表歉意,但我在StackOverflow上发现,经过深思熟虑的问题会得到更好的答案。

    这个问题被称为“复杂的工作拷贝问题”。RyanTomayko有一篇名为的博客文章,详细讨论了这个问题以及Git如何解决这个问题


    这是Git最好的地方之一。我至少每天使用
    gitadd-p
    ,来帮助提交独立于彼此的代码块。两个逻辑上不同的更改位于同一源文件中这一事实已变得无关紧要。

    ClearCase还支持更改列表(在其UCM风格中称为“活动”),并提出了类似的挑战

    只有当您确定“调试工作”与当前开发工作(电子邮件功能)不兼容并且最好保存在单独的分支中时,选项1(“分支类型”)才有意义。然后,您可以将“补丁”分支中所做的任何更正改装到主分支(因为并非您将修复的每个bug都必须同时出现在这两个分支中:当前的开发可能会使某些修复过时)。
    另请参见“”,以及您的目标是什么

    选项3说明了变更集概念的局限性:文件的单个修订(或“版本”)一次只能是一个变更集的一部分

    git add-p
    (add patch)是选项1和3的替代选项,因为它利用了“索引”(暂存区)的暂存功能,您可以在其中决定实际提交的内容以及保留在私人空间中的内容。
    这很好,但根据我的经验,很难在很长一段时间内保持,尤其是在一组通用的文件上,您应用了两种不同的演变。分支更干净,更易于单元测试。然而,对于你提到的一个小补丁,这可能是一个很好的解决方法

    选项2是一个实用的解决方案,当您意识到您对两种不同的工作有两种更改时(它们仍然兼容,不会“破坏”彼此)。
    但更简单的解决方案可能是:

    • 在电子邮件中签入main.h的当前状态
    • 签入bug,修复它,签入bug
    • 然后在电子邮件中签出以恢复电子邮件功能开发

    同样,如果两个开发工作(电子邮件和bug)兼容,您可以有一个混合活动的修订历史记录。

    我们使用作业,以便单个“任务”可以跨越多个提交的变更集

    因此:

  • 检查main.h变更与其他变更无关
  • 签入main.h的当前状态-在长期电子邮件作业下
  • 对main.h进行bug修复吗
  • 签入错误修复变更集
  • 如果需要,在电子邮件作业下编辑main.h

  • 例如,您可以使用工具l