您对合并代码感到舒服吗?
今天早上,我读到了两个关于重构的观点。
- 意见 1(页面不存在)
- 意见 2(页面不存在)
他们建议分支(并随后合并)代码以:
- 保持主干干净。
- 允许开发人员远离有风险的更改。
根据我的经验(尤其是 Borland 的 StarTeam),合并是一项并不简单的操作。出于这个原因,我只在必须时才分支(即当我想冻结候选版本时)。
从理论上讲,分支是有意义的,但合并的机制使其成为一种非常危险的操作。
我的问题:
- 您对合并代码感到满意吗?
- 您是否出于冻结版本以外的原因分支代码 候选人?
This morning, I read two opinions on refactoring.
- Opinion 1 (Page not present)
- Opinion 2 (Page not present)
They recommend branching (and subsequently merging) code to:
- Keep the trunk clean.
- Allow a developer to walk away from risky changes.
In my experience (particularly with Borland's StarTeam), merging is a non-trival operation. And for that reason, I branch only when I must (i.e. when I want to freeze a release candidate).
In theory, branching makes sense, but the mechanics of merging make it a very risky operation.
My questions:
- Do you feel comfortable merging code?
- Do you branch code for reasons other than freezing a release
candidate?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
我只做过几次,所以我对此不太满意。
我这样做是为了进行跨越一些签到的设计实验,因此分支是一种简单的方法,可以为自己隔离一个可以玩耍的花园。此外,它允许我在其他人在主分支上工作时进行修补,所以我们并没有损失太多时间。
当进行大范围的更改时,我也会这样做,这会导致主干无法编译。在我的项目中,很明显我必须删除大部分代码库的编译时类型安全性(从泛型到 system.object)。我知道这需要一段时间,并且需要对整个代码库进行更改,这会干扰其他人的工作。它还会破坏构建,直到我完成为止。因此,我进行了分支并剥离了泛型,直到该分支编译为止。然后我把它合并回后备箱。
结果很好。防止了很多脚趾踩踏的情况,这很棒。希望类似的事情不再发生。设计需要进行广泛的编辑而不会导致大量代码被丢弃,这是一种罕见的事情......
I've only done it a couple times, so I'm not exactly comfortable with it.
I've done it to conduct design experiments that would span over some checkins, so branching is an easy way to wall off yourself a garden to play in. Also, it allowed me to tinker while other people worked on the main branch, so we didn't lose much time.
I've also done it when making wide ranging changes that would render the trunk uncompilable. It became clear in my project that I'd have to remove compile-time type safety for a large portion of the codebase (go from generics to system.object). I knew this would take a while and would require changes all over the codebase which would interfere with other people's work. It would also break the build until I was complete. So I branched and stripped out the generics, working until that branch compiled. I then merged it back into the trunk.
This turned out pretty well. Prevented a lot of toe-stepping, which was great. Hopefully nothing like this will ever come up again. Its kind of a rare thing that a design will change requiring this kind of wide ranging edits that don't result in a lot of code being thrown out...
必须正确管理分支才能使合并变得轻松。根据我(使用 Perforce)的经验,从主线定期集成到分支意味着集成回主线非常顺利。
合并失败的情况极为罕见。从主线到分支的持续集成很可能涉及合并,但它们只是自动工具无需人工干预即可处理的小编辑。这意味着用户没有“看到”这些发生。
因此,最终集成中所需的任何合并通常也可以自动处理。
Perforces 3 路合并工具在实际需要时提供了很大的帮助。
Branched have to be managed correctly to make merging painless. In my experience (with Perforce) regular integration to the branch from the main line meant that the integration back into the main line went very smoothly.
There were only rare occasions when the merging failed. The constant integration from the main line to the branch may well have involved merges, but they were only of small edits that the automatic tools could handle without human intervention. This meant that the user didn't "see" these happening.
Thus any merges required in the final integration could often be handled automatically too.
Perforces 3-way merge tools were a great help when they were actually needed.
这实际上取决于我使用的工具。对于 Starteam,分支确实不是一件小事(说实话,Starteam 在分支方面很糟糕)。使用 Git,分支是一项常规活动,而且非常简单。
嗯,这确实取决于您的版本控制模式,但简短的答案是肯定的。实际上,我建议阅读以下文章:
我真的很喜欢第一篇文章中描述的模式,它可以可应用于任何(非分布式)版本控制系统,包括 Starteam。
我可能会考虑第二种方法(实际上,两种策略的混合)与(且仅与)分布式版本控制系统(DVCS),如 Git、Mercurial...
It really depends of the tool I'm using. With Starteam, branching is indeed non trivial (TBH, Starteam sucks at branching). With Git, branching is a regular activity and is very easy.
Well, this really depends of your version control pattern but the short answer is yes. Actually, I suggest to read the following articles:
I really like the pattern described in the first article and it can be applied with any (non Distributed) Version Control System, including Starteam.
I might consider the second approach (actually, a mix of the both strategies) with (and only with) a Distributed Version Control Systems (DVCS) like Git, Mercurial...
我们使用 StarTeam,并且仅在需要它的情况下才进行分支(即发布周期中的生产热修复或某些跨越多个发布窗口的长期项目)。我们使用视图标签来识别版本,这使得以后根据需要创建分支变得很简单。所有构建都基于这些视图标签,我们不会构建非标签代码。
开发人员应该遵循“代码 - 测试 - 提交”模型,如果他们需要用于某些测试目的或“风险”开发的视图,他们会创建并管理它。我管理存储库并仅在需要时创建分支。这些时间包括(但不限于):
StarTeam 中的合并工具不是最好的,但我还没有遇到由它引起的问题。无论是谁进行合并,都需要非常确定他们知道自己在做什么。
在 Star Team 中创建“只读参考”视图并将其设置为浮动配置将允许主干中的更改自动显示在分支中。将项目设置为在更改时分支。这有利于并发开发工作。
创建带有标签配置的“只读参考”视图是您对现有生产版本进行热修复的方法(假设您已对它们进行了标签)。
We use StarTeam and we only branch when we have a situation that requires it (i.e. hotfix to production during release cycle or some long reaching project that spans multiple release windows). We use View Labels to identify releases and that makes it a simple matter to create branches later as needed. All builds are based on these view labels and we don't build non-labeled code.
Developers should be following a "code - test - commit" model and if they need a view for some testing purpose or "risky" development they create it and manage it. I manage the repository and create branches only when we need them. Those times are (but not limited to):
The merge tool in StarTeam is not the greatest, but I have yet to run into an issue caused by it. Whoever is doing the merge just needs to be VERY certain they know what they're doing.
Creating a "Read Only Reference" view in Star Team and setting it to a floating configuration will allow changes in the trunk to automatically show in the branch. Set items to branch on change. This is good for concurrent development efforts.
Creating a "Read Only Reference" view with a labeled configuration is what you'd use for hot fixes to existing production releases (assuming you've labeled them).
正如大多数人所回答的那样,分支是微不足道的,但正如您所说,合并则不然。
真正的关键是解耦和单元测试。尝试在分支之前解耦,并密切关注主干线以确保解耦和接口得到维护。这样,当需要合并时,就像更换乐高积木一样:移除旧的部件,新的部件完美地安装在其位置上。单元测试是为了确保没有任何问题。
Branching is trivial, as most have answered, but merging, as you say, is not.
The real keys are decoupling and unit tests. Try to decouple before you branch, and keep an eye on the main to be sure that the decoupling and interface are maintained. That way when it comes time to merge, it's like replacing a lego piece: remove the old piece, and the new piece fits perfectly in its place. The unit tests are there to ensure that nothing got broken.
分支和合并应该相当简单。
有几种不同的分支模型:
这是一个
现在这是一件奇怪的事情。假设 Release1 需要一些错误修复。现在您需要分支Release1来开发1.1。没关系,因为现在您可以分支 R1,完成您的工作,然后合并回 R1 以形成 R1.1。请注意这如何使版本之间的差异保持清晰?
另一种分支模型是在主干上完成所有开发,并且每个版本都会被标记,但在该特定版本上不会进行进一步的开发。分支的出现是为了发展。
可能还有一两个其他主要的分支模型,我一时想不起来。
最重要的是,您的 VCS 需要支持灵活的分支和合并。
IMO(RCS、Clearcase、CVS)中的每个文件 VCS 系统是一个主要难题。
据说 SVN 在这里也很麻烦,不知道为什么。
Mercurial 在这里做得很好,(我认为)git 也是如此。
Branching and merging should be fairly straightforward.
There's a few different branch models:
Here's a one
Now here's a curious thing. Suppose Release1 needed some bugfixing. Now you need to branch Release1 to develop 1.1. That is OK, because now you can branch R1, do your work, and then merge back to R1 to form R1.1. Notice how this keeps the diffs clear between releases?
Another branching model is to have all development done on the Trunk, and each release gets tagged, but no further development gets done on that particular release. Branches happen for development.
There may be one or two other major branch models, I can't recall them off the top of my head.
The bottom line is, your VCS needs to support flexible branching and merging.
Per-file VCS systems present a major pain IMO(RCS, Clearcase, CVS).
SVN is said to be a hassle here as well, not sure why.
Mercurial does a great job here, as does(I think)git.
分支可能会很痛苦,但其实不应该如此。
这就是类似 git 的项目(mercurial、bazar)告诉我们的 CVS 和 SVN。在 git 和 Mercurial 上,分支很容易。在 SVN 上这很容易,但对于大型项目来说,管理起来可能有点困难(因为与 git 和 Mercurial 等其他一些项目相比,分支/合并过程所花费的时间可能会很长,如果没有- 明显的冲突)。这并不能帮助不习惯经常分支的用户对分支有信心。许多用户没有意识到分支的强大用途,只是远离分支,以免给他们的项目添加新问题,让对未知的恐惧使他们远离效率。
分支应该是一个简单而强大的工具,我们出于任何原因都必须使用它来进行分支。
建立分支的一些充分理由:
Branching might be painful but it shouldn't be.
That's what git-like projects (mercurial, bazar) tells us about CVS and SVN. On git and mercurial, branching is easy. On SVN it's easy but with big projects it can be a bit hardcore to manage (because of time spent on the branching/merging process that can be very long -- compared to some others like git and mercurial -- and difficult if there are non-obvious conflicts). That don't help users that are not used to branch often to have confidence in branching. Lot of users unaware of the powerful uses of branching just keep it away to not add new problems to their projects, letting the fear of the unknown make them far from efficiency.
Branching should be an easy and powerful tool we'd have to use for any reason good enough to branch.
Some good reasons to branchs:
一些松散的指导原则:
分支只是另一种工具,您如果你想获得最大的利益,就需要学习如何有效地使用它。
您对分布式开源项目(例如 Git 上的项目)和公司开发项目(可能在 SVN 上运行)之间的分支态度可能有所不同。对于分布式项目,您需要鼓励分支以最大化创新和实验,对于后一种类型,您需要更严格的控制并为每个代码行规定签入策略,这些代码行规定何时应该/不应该发生分支,主要是为了“保护”代码。
这是分支指南:
http://www.vance.com/steve/perforce/Branching_Strategies.html
这是一个简短的指南,其中包含一些高级最佳实践:
https://www.perforce.com/pdf/scm-best-practices。 pdf
Some loose guiding principles:
Branching is just another tool, you need to learn how to use it effectively if you want the maximum benefit.
Your attitude to branching should probably differ between distributed open source projects (such as those on Git) and your company's development projects (possibly running on SVN). For distributed projects you'll want to encourage branching to maximize innovation and experimentation, for the latter variety you'll want tighter control and to dictate checkin policies for each code line that dictate when branching should / should not occur, mostly to "protect" the code.
Here is a guide to branching:
http://www.vance.com/steve/perforce/Branching_Strategies.html
Here is a shorter guide with some high level best practices:
https://www.perforce.com/pdf/scm-best-practices.pdf
分支是微不足道的。合并则不然。因此,我们很少分支任何东西。
Branching is trivial. Merging is not. For that reason, we rarely branch anything.
使用 SVN,我发现分支相对轻松。特别是如果您定期将主干合并到分支中以防止其过于不同步。
Using SVN, I've found branching to be relatively painless. Especially if you periodically merge the trunk into your branch to keep it from getting too far out of sync.
我们使用svn。我们只需要大约 5 分钟就可以完成分支代码。与它让我们避免弄乱躯干所带来的痛苦相比,这简直是微不足道的。
We use svn. It only takes us about 5 minutes to branch code. It's trivial compared to the amount of pain it saves us from messing up trunk.
在由数百万行代码组成的代码库中工作,并有数百名开发人员进行分支工作是司空见惯的事情。分支的寿命根据所完成的工作量而变化。
对于一个小修复:
对于多人团队功能:
对于客户软件版本:
传播 客户发布流支持成本可能非常昂贵。需要测试资源——人员和设备。一两年后,随着主流的发展,开发人员对特定流的知识开始变得陈旧。
你能想象微软要同时支持 XP、Vista 和 Windows 7 需要花费多少钱吗?考虑测试台、管理、文档、客户服务,最后是开发团队。
黄金法则:永远不要打破主流,因为这样可能会阻碍大量开发人员。 $$$
Working in a code base of millions of lines of code with hundreds of developers branching is an everyday occurrence. The life of the branch varies depending on the amount of work being done.
For a small fix:
For a multi-person team feature:
For a customer software release:
Customer release streams can be very expensive to support. Requires testing resources - people and equipment. After a year or two, developer knowledge on specific streams starts to get stale as the main stream moves forward.
Can you imagine how much it must cost for Microsoft to support XP, Vista and Windows 7 concurrently? Think about the test beds, the administration, documentation, customer service, and finally the developer teams.
Golden rule: Never break the main stream since you can stall a large number of developers. $$$
分支问题是我使用分布式版本控制系统(在我的例子中是 Git,但也有 Mercurial 和 Bazaar)的原因,其中创建分支是微不足道的。
我一直使用短期分支进行开发。这让我在自己的存储库中搞乱,犯错误和错误的选择,然后将更改重新设置到主分支,这样只有干净的更改才会保留在历史中。
我使用
标签
来标记冻结代码,并且在这些系统中很容易返回并分支这些代码以修复错误,而无需在代码库中加载长期存在的分支。The branching problem is why I use a Distributed Version Control system (Git in my case, but there are also Mercurial and Bazaar) where creating a branch is trivial.
I use short lived branches all the time for development. This lets me mess around in my own repository, make mistakes and bad choices, and then
rebase
the changes to the main branch so only clean changes are kept in history.I use
tag
s to mark frozen code, and it is easy in these systems to go back and branch off these for bug fixes without having a load of long lived branches in the code base.我使用 Subversion 并认为分支非常简单和容易。所以回答问题 1.. 是的。
分支的原因可能有很大差异。如果我觉得应该的话,我就会分支。很难为所有可能性制定规则和理由。
然而,就“允许开发人员远离有风险的更改”而言。评论。我完全同意这一点。每当我想真正玩弄代码并希望我是唯一从事该工作的开发人员时,我都会创建一个分支。当您分支时,您可以这样做...
I use Subversion and consider branching very simple and easy. So to answer question 1.. Yes.
The reason for branching can vary massively. I branch if I feel I should. Quite hard to put rules and reasons down for all possibilities.
However, as far as the "Allow a developer to walk away from risky changes." comment. I totaly agree with that one. I create a branch whenever I want to really play around with the code and wish I was the only developer working on it.. When you branch, you can do that...
我一直在使用 svn 和 TFS 进行一个项目,并且分支本身是一件非常简单的事情。
我们使用分支来发布候选版本以及持久或实验性功能,并隔离其他团队的干扰。
分支中唯一痛苦的时刻是合并,因为旧的或高度开发的分支可能与主干有很大不同,并且可能需要付出巨大的努力才能合并回来。
如上所述,我想说分支是一种强大且有用的实践,在开发时应该考虑到。
I've been on a project using svn and TFS and branching by itself is a really simple thing.
We used branching for release candidate as well as for long lasting or experimental features and for isolating from other team's interference.
The only painful moment in branching is merging, because an old or intensely developed branch may differ a lot from trunk and might require significant effort to merge back.
Having said the above, I would say that branching is a powerful and useful practice which should be taken into account while developing.
如果合并太痛苦,请考虑迁移到更好的 VCS。那将是更大的痛苦,但只有一次。
If merging is too much of a pain, consider migrating to a better VCS. That will be a bigger pain, but only once.
我们使用 svn 并采用了分支重大更改的规则。小改动是在后备箱中完成的。
我们还分支发布。
分支和合并对我们来说效果很好。诚然,有时我们必须坐下来思考如何将事物组合在一起,但通常 svn 在合并所有内容方面做得很好。
We use svn and have adopted a rule to branch breaking changes. Minor changes are done right in the trunk.
We also branch releases.
Branching and merging have worked well for us. Granted there are times we have to sit and think about how things fit together, but typically svn does a great job of merging everything.
我使用svn,分支代码只需要不到一分钟的时间。我以前使用Clearcase,分支代码只用了不到一分钟。我还使用过其他较小的 SCM,它们要么不支持分支,要么使用起来太痛苦。 Starteam 听起来像是后者。
因此,如果您无法迁移到更有用的方法(实际上,我只听说过 Starteam 的坏消息),那么您可能必须尝试一种不同的方法:手动分支。这涉及检查您的代码,将其复制到不同的目录,然后将其添加为新目录。当您需要合并时,您可以检出两个目录并使用 WinMerge 执行合并,将结果检入原始目录。如果您继续使用该分支,这会很尴尬并且可能会很困难,但它确实有效。
分支的诀窍在于不要将其视为全新产品。它是一个分支 - 一种生命周期相对较短的设备,用于单独且安全地对主产品主干进行更改。任何认为合并很困难的人要么重构代码文件太多(即重命名、复制、创建新的、删除旧的)以至于分支变成完全不同的东西,要么他们保留分支太久以至于累积的更改承担与原作几乎没有相似之处。
您可以长期保留分支,只需定期合并更改即可。这样做,分支/合并变得非常容易。
I use svn, it takes less than a minute to branch code. I used to use Clearcase, it took less than a minute to branch code. I've also used other, lesser, SCMs and they either didn't support branches or were too painful to use. Starteam sounds like the latter.
So, if you cannot migrate to a more useful one (actually, I've only heard bad things about Starteam) then you might have to try a different approach: manual branching. This involves checking out your code, copying it to a different directory and then adding it as a new directory. When you need to merge, you'd check out both directories and use WinMerge to perform the merge, checking in the results to the original directory. Awkward and potentially difficult if you continue to use the branch, but it works.
the trick with Branching is not to treat it as a completely new product. It is a branch - a relatively short-lived device used to make changes separately and safely to a main product trunk. Anyone who thinks merging is difficult is either refactoring the code files so much (ie they are renaming, copying, creating new, deleting old) that the branch becomes a completely different thing, or they are keeping the branch so long that the accumulated changes bear little resemblance to the original.
You can keep a branch for a long time, you just have to merge your changes back regularly. Do this and branching/merging becomes very easy.