如何在Mercurial DVCS中执行提交策略

4
对于一个小型软件开发项目,我希望更改能遵循一个定义好的流程,其中集成分支仅包含“完整”的更改。这个想法源自我关于如何从Mercurial获取有用的历史日志的博客文章。然而,这不仅仅是关于生成日志,而是关于一种有结构的工作方式。
总之,这个想法是,一个代码库将拥有一个“集成”分支,该分支不会直接进行开发,任何工作都将在另一个分支上进行,当完成后将被合并到集成分支中 - 下面是一个粗略的例子,其中提交注释用大括号表示:
  O   {Implemented new feature X}
  |\
  | O {...}
  | |
  | O {...}
  |/
  O   {Fixed bug 002}
  |\
  | O {...}
  |/
  O   {added tag "Release 1.0"}
  |
  O   {Fixed bug 001}
  |\
  | O {...}
  |/
  O  -- integration branch
 /
O  -- default branch

"integration"分支只允许合并和标记。这类似于我们在工作中开发(在基于服务器的非DVCS系统上)的方式,您可以在工作分支上进行更改,完成后(经过审核、测试等)将这些更改合并到集成分支中进行正式测试和发布。无论如何,我的问题是 - 我如何强制执行仅在工作分支上进行更改的策略,同时在集成分支上只允许合并或标记?我最初的想法是在pre-commit上添加钩子(不是precommitpretxncommit,因为我认为这些会在您创建标记时触发)。如果您在集成分支上,该钩子将检查是否有两个父级,表示这是合并的结果,并在不是这种情况下失败。但是据我所知,当您克隆存储库时,钩子不会被复制。由于这将是一个项目特定的设置,因此不应在用户级别设置。那么,我如何阻止用户克隆存储库(从而丢失挂钩),直接在集成分支上进行更改,然后推送?"
hg clone main_repo
hg update integration_branch
(make changes without starting a new branch)
hg commit -m "I made some changes"
hg push

另外,如果使用类似Bitbucket这样的系统,我该如何执行此操作?

或者说,在使用分布式版本控制系统时,这不是正确的工作流程吗?


2
你能不能让大家都同意不对集成分支进行更改呢? - Zhehao Mao
当然,这是一个选项,但我更倾向于阻止意外更改... 这意味着你可以进行更改,但除非你执行了 hg branch newbranch,否则提交将失败。 - icabod
我认为你的评论更多地涉及Mercurial,因此它的主题应该更好地称为“如何在Mercurial DVCS中执行提交策略”。 - bialix
bialix:已经注意并更改了。我最初是在考虑任何分布式版本控制系统中应该如何完成,但无论如何我都是Mercurial用户 :) - icabod
2个回答

2
我认为你说的“有组织的工作方式”可能是指代码中尉。这意味着门从内部锁定,只有中尉才能打开它,并且只有当中尉拉取时,代码才会击中中央存储库。通过您的批准流程的代码将被拉入中央或权威存储库,这是一种“有组织的工作方式”。
如果您只拒绝在存储库中一个分支的写入权限,而不是拒绝对整个中央存储库的写入权限,那么我觉得您几乎是在问如何削弱DVCS的最大优点:(a)不仅有一个副本,每个副本都可以具有自己的读/写访问规则,其中一个副本是中央副本,如果您希望是这样的话;(b)提交与将其施加于任何其他人是分离的。提交是本地工作副本操作。只有在这些提交到达权威存储库(中央存储库或由您的代码中尉管理的存储库)之后,您才使用DVCS在受控过程下进行了真正的更改。
或者您是否认为用户甚至不应该在没有创建分支的情况下提交到他们自己的本地DVCS实例中?
简而言之,您可以说,每个本地机器的工作副本都是一个分支,一个不可见的分支,没有施加于任何人,甚至没有名称,直到由中尉进行代码审查,并对整个更改集进行集成测试,这在功能上等同于您可能在CVCS中称为“特性分支”的东西。这些不可见的分支都是可写的,而中央存储库(不是分支,而是单独的存储库)是只读的,通过它的设置实现;用户可以从中同步,但不能向其中推送,除非中尉将新更改拉入其中。基本上很稳定,但仍然可以让每个人完成工作。

虽然这是一个不错的工作流(对于这个问题而言是一个合理的解决方案),但它并没有使得技术提交规则(例如通过钩子)完全过时。如果开发人员在早期阶段,即当他们提交或推送代码时,认识到他们违反了工作流规则,那么代码检查员就不必处理意外违反的规则,而可以集中精力解决更复杂的问题。 - Oben Sonne
我认为将这些东西结合起来的好方法是使用代码钩子自动构建提交到中央仓库,然后可以标记为“通过冒烟测试”或其他内容,甚至可以进行手动QA审查以标记构建为良好的集成阻止。但是,如果您实际上阻止提交,则会阻止工作。阻止集成移动(拉/推)而不是提交。 - Warren P
已接受的答案。我认为这让我远离了钩子的想法,而是允许每个克隆的存储库成为其自己的分支(毕竟这是Mercurial作为DVCS的一种方式)。中央存储库仅限拉取的想法也很好 - 将此与类似于Bitbucket或类似服务相结合,可能通过用户可以从中工作的分支来实现,主要存储库仅可由负责人推送。 - icabod
@Warren P:在“有代码钩子引起对中央仓库提交的自动构建,然后可以将其标记为‘通过冒烟测试’”的情况下,实现了哪些标记机制?这些机制是像标签/书签这样的Mercurial内部手段,还是像CI工具日志和自制标记管理器这样的外部手段? - dim
标记机制可以包括修改提交日志注释以包含标记,例如在提交注释中添加标签“[PASSED_SMOKE_TEST:yy-mm-dd hh:nn]”,或者可以使用BookmarksExtension创建标签或书签,例如可以创建一个名为“BOOKMARK_LATEST_PASSED_SMOKE_TEST”的书签。 - Warren P

1

如果您可以访问中央仓库的hgrc,您可以定义一个pretxnchangegroup钩子,验证集成分支上的传入变更集是否有2个父级(第一个必须在集成分支上)。据我所知,在Bitbucket上,您只能使用brokers设置后检查。这些代理不会阻止任何不必要的推送,但可能会通知您,以防有人没有遵循规则。

然而,就个人而言,我赞同@Zhehao的评论,即尽量让每个人都遵守规则,让那些违反规则的人为同事们服务一周咖啡(或者其他方式)。

最后,您可以维护一些共享的hgrc和相应的钩子,每个开发人员都必须在其系统上设置(一次)。如果在系统上全局设置,则无需为每个克隆设置它们。


2
对于共享的hgrc,如果您只想让钩子适用于特定存储库的克隆版本,您还可以在钩子中检查当前存储库中初始提交的哈希/ID。 - Tim Delaney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接