如何管理与Mercurial的并发开发? [英] How to manage concurrent development with mercurial?

查看:41
本文介绍了如何管理与Mercurial的并发开发?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个最佳实践问题,我希望答案是取决于情况".我只是希望了解更多实际场景和工作流程.

首先,我说的是同一项目的不同更改,所以请不要进行子仓库.

假设您的代码库位于hg存储库中.您开始研究复杂的新功能A,然后您值得信赖的测试人员(您有测试人员,对吧)报告了一个复杂的错误B.

如果B的(解决方法)依赖于A,这是微不足道的.您先是ci A然后是ci B.

我的问题是当他们独立时(或至少现在看来)该怎么办.

我可以想到以下几种方式:

  1. 为B使用单独的克隆.
  2. 在同一存储库中使用匿名或命名分支或书签.
  3. 使用MQ(A上有B补丁).
  4. 使用分支MQ(稍后再解释).
  5. 使用多个MQ(从1.6开始)

1和2由优秀@Steve Losh撰写的博客,该链接来自稍相关的问题. >

1相对于其他选择的一个巨大优点是,当您从处理一件事情切换到另一件事情时,它不需要任何重建,因为文件在物理上是分离且独立的.因此,例如,如果A和/或B触摸定义了三态布尔值且包含在成千上万个C文件中的头文件,则它实际上是唯一的选择(不要告诉我您还没有看到这样的旧代码基本).

3可能是最简单的(就设置和开销而言),如果B是小的和/或紧急修复程序,则可以翻转A和B的顺序.但是,如果A和B触摸相同的文件,可能会变得棘手.如果A和B更改在同一个文件中是正交的,则修复无法应用的补丁块很容易,但是从概念上讲还是有一定风险的.

4会让您晕眩,但这是最强大,最灵活和可扩展的方式.我默认将hg qinit-c设置为默认值,因为我想标记进行中的补丁程序并将其推入/拉出,但是要意识到您也可以在MQ回购中分支,确实需要进行概念上的飞跃.步骤如下(mq = hg --mq):

  1. hg qnew bugA;为A进行更改; hg qref
  2. mq branch branchA; hg qci
  3. hg qpop; mq up -rtip^
  4. hg qnew bugB;为B进行更改; hg qref
  5. mq branch branchB; hg qci
  6. 再次使用A:hg qpop; mq up branchA; hg qpush

采取这么多步骤似乎很疯狂,每当您需要切换工作时,都必须hg qci; hg qpop; mq up <branch>; hg qpush.但是考虑一下:您在同一个存储库中有几个已命名的发行分支,并且您需要同时为所有这些项目处理多个项目和错误修复程序(您最好获得这种工作的保证奖金).使用其他方法很快就会迷路.

现在,我的同伴恋人,还有其他/更好的选择吗?


(更新)qqueue几乎使#4过时了.参见Steve Losh的优雅描述解决方案

似乎没有比我在问题中列出的选择更多或更好的选择了.所以他们又来了.

  1. 每个项目使用一个克隆.
    • 优点:完全隔离,因此在切换项目时无需重建.
    • 缺点:工具链需要在两个克隆之间切换.
  2. 在同一存储库中使用匿名或命名分支或书签.
    • 优点:标准汞(或任何DVCS)做法;干净整洁.
    • 缺点:必须在切换前提交,然后再重建.
  3. 在每个项目中将MQ与一个补丁(或多个连续补丁)一起使用.
    • 优点:简单易用.
    • 缺点:必须在切换之前进行qrefresh并在之后进行重建;如果项目不是正交的,那将是棘手的和冒险的.
  4. 每个项目使用一个MQ分支(或1.6+中的qqueue).
    • 优点:超灵活且可扩展(针对并发项目的数量)
    • 缺点:必须在切换之前进行qrefreshqcommit并在之后进行重建;感觉很复杂.

像往常一样,没有灵丹妙药,因此请选择一项合适的工作.


(更新)对于任何喜欢MQ的人来说,在常规分支(#2 +#3)之上使用MQ可能是最常见和可取的做法.

如果您有两个在两个分支上都有基线的并发项目(例如下一个版本和当前版本),那么在它们之间进行跳转是很简单的:

hg qnew; {coding}; hg qrefresh; {repeat}
hg qfinish -a
hg update -r <branch/bookmark/rev>
hg qimport -r <rev>; {repeat}

对于最后一步,qimport应该添加一个-a选项以一次导入一行变更集.希望盖斯勒先生注意到这一点:)

This is a best practice question, and I expect the answer to be "it depends". I just hope to learn more real world scenarios and workflows.

First of all, I'm talking about different changes for the same project, so no subrepo please.

Let's say you have your code base in an hg repository. You start to work on a complicated new feature A, then a complicated bug B is reported by your trusted tester (you have testers, right?).

It's trivial if (the fix for) B depends on A. You simlply ci A then ci B.

My question is what to do when they are independent (or at least it seems now).

I can think of the following ways:

  1. Use a separate clone for B.
  2. Use anonymous or named branches, or bookmarks, in the same repository.
  3. Use MQ (with B patch on top of A).
  4. Use branched MQ (I'll explain later).
  5. Use multiple MQ (since 1.6)

1 and 2 are covered by an excellent blog by @Steve Losh linked from a slightly related question.

The one huge advantage of 1 over the other choices is that it doesn't require any rebuild when you switch from working on one thing to the other, because the files are physically separated and independent. So it's really the only choice if, for example, A and/or B touches a header file that defines a tri-state boolean and is included by thousands of C files (don't tell me you haven't seen such a legacy code base).

3 is probably the easiest (in terms of setup and overhead), and you can flip the order of A and B if B is a small and/or urgent fix. However it can get tricky if A and B touches the same file(s). It's easy to fix patch hunks that failed to apply if A and B changes are orthogonal within the same file(s), but conceptually it's still a bit risky.

4 can make you dizzy but it's the most powerful and flexible and scalable way. I default hg qinit with -c since I want to mark work-in-progress patches and push/pull them, but it does take a conceptual leap to realize that you can branch in MQ repo too. Here are the steps (mq = hg --mq):

  1. hg qnew bugA; make changes for A; hg qref
  2. mq branch branchA; hg qci
  3. hg qpop; mq up -rtip^
  4. hg qnew bugB; make changes for B; hg qref
  5. mq branch branchB; hg qci
  6. To work on A again: hg qpop; mq up branchA; hg qpush

It seems crazy to take so many steps, and whenever you need to switch work you must hg qci; hg qpop; mq up <branch>; hg qpush. But consider this: you have several named release branches in the same repository, and you need to work on several projects and bug fixes at the same time for all of them (you'd better get guaranteed bonus for this kind of work). You'd get lost very soon with the other approaches.

Now my fellow hg lovers, are there other/better alternatives?


(UPDATE) qqueue almost makes #4 obsolete. See Steve Losh's elegant description here.

解决方案

It seems like there's no more or better choices than the ones I listed in the question. So here they are again.

  1. Use one clone per project.
    • Pros: total separation, thus no rebuild when switching projects.
    • Cons: toolchain needs to switch between two clones.
  2. Use anonymous or named branches, or bookmarks, in the same repository.
    • Pros: standard hg (or any DVCS) practice; clean and clear.
    • Cons: must commit before switching and rebuild after.
  3. Use MQ with one patch (or multiple consecutive patches) per project.
    • Pros: simple and easy.
    • Cons: must qrefresh before switching and rebuild after; tricky and risky if projects are not orthogonal.
  4. Use one MQ branch (or qqueue in 1.6+) per project.
    • Pros: ultra flexible and scalable (for the number of concurrent projects)
    • Cons: must qrefresh and qcommit before switching and rebuild after; feels complicated.

Like always, there's no silver bullet, so pick and choose the one right for the job.


(UPDATE) For anyone who's in love with MQ, using MQ on top of regular branches (#2 + #3) is probably the most common and preferable practice.

If you have two concurrent projects with baseline on two branches (for example next release and current release), it's trivial to hop between them like this:

hg qnew; {coding}; hg qrefresh; {repeat}
hg qfinish -a
hg update -r <branch/bookmark/rev>
hg qimport -r <rev>; {repeat}

For the last step, qimport should add a -a option to import a line of changesets at once. I hope Meister Geisler notices this :)

这篇关于如何管理与Mercurial的并发开发?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆