如何在不失去理智的情况下重构分支?
我一直重构我和其他人的代码。 当我在分支而不是主干中工作时,这有时会导致一些极其痛苦的合并,特别是如果我不定期合并回主干(分支上的代码慢慢地从主干转移,当人们修改主干时,我必须手动弄清楚如何将其应用到分支)。
我知道的解决方案是
- 不断地与主干合并 - 减少痛苦的合并,但是为什么要在分支中工作呢?
- 每当你需要重构某些东西时,切换到 Trunk,在那里进行重构并合并到你的分支 - 我觉得这不太实用,因为每次重构切换环境的实际成本是巨大的。
你做什么工作?
I refactor my and other people's code all the time.
When I work in a branch and not in Trunk, this sometimes results in some extremely painful merges, especially if I don't merge back to Trunk regularly (the code at the branch slowly shifts away from the Trunc, and when people modify Trunk I have to figure out manually how to apply this to the branch).
The solutions I know are either
- Constantly merge to and from Trunk - reduces painful merges, but then why work in a branch at all?
- Whenever you need to refactor something, switch to Trunk, do the refactoring there and merge to your branch - I don't find this very practical, since the actual cost of switching environments for every refactoring is huge.
What do you do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
尽早承诺,经常承诺。
或者在这种情况下......尽早合并,经常合并。
Commit early, commit often.
Or in this case... Merge early, merge often.
持续集成是关键...一次一小批更改...
Continuous integration is the key... 1 small batch of changes at a time...
冒着显而易见的风险,我想说尽量避免完全分支。 决不能低估由此造成的开销。 即使您认为不能再拖延了(在生产中发布一个系统,正在构建两个版本,而且还更改发布一个系统的请求),仍然尝试寻找另一种方法:是否真的没有办法可以在不分支的情况下隔离功能(例如,拆分“公共”项目和一些子项目)? 难道真的没有办法集成所有代码吗(例如创建包含差异的策略类或创建开关来打开或关闭新功能)?
如果您绝对必须进行分支,我会选择选项 1。尝试合并尽可能小的更改并经常进行。
At the risk of being obvious, I'd say try to avoid branching altogether. The amount of overhead this causes must not be underestimated. Even when you think you can't hold off any longer (release one of system in production, release two being built but also change requests to release one) still try to find another way: Is there really no way you can isolate functionality without branching (e.g. split off a "common" project and some subprojects)? Is there really no way you can integrate all code on the head (e.g. create Strategy classes that incorporate the differences or create switches to turn new features on or off)?
If you absolutely have to branch, I'd go with option 1. Try to merge as small changes as possible and do it frequently.
大规模重构需要在开发时间线的正确时间进行。 如果您在发布前进行大量重构,您最终会伤害自己,因为您会在应该最小化更改的时候引入痛苦的合并。 重构的破坏性越大,它应该在开发周期的早期发生(并且应该有更特殊的过程,例如在一段时间内尽可能停止对受影响文件的编辑)。
不断地与主干合并通常是很好的做法。
在这种情况下,为什么还要在分支机构工作呢? 因为您拥有更多控制权(例如,您可以停止合并到主干以稳定其发布,而无需停止签入您的开发分支)。 因为您可以围绕与主干的合并或从主干的合并进行高级别验证,而不会过多影响到开发分支的签入速度。
Refactoring on a large scale needs to be done at the right time in the development timeline. If you do huge amounts of refactoring near release you'll end up hurting yourself because you'll introduce painful merges at a time when changes should be minimized. The more disruptive your refactoring will be the earlier in the development cycle it should happen (and the more special process there should be for it, e.g. stop edits to the affected files as much as possible for a period of time).
Constantly merging to and from trunk is generally good practice.
Why work in a branch at all in that case? Because you have more control (you can stop merging into trunk to stabilize it for release, for example, without stopping checkins to your development branch). Because you can place a high level of validation around merging to/from trunk without impacting checkin velocity to the development branch much.
我选择 1,尽可能进行小的更改并经常检查,否则合并会变得痛苦。 如果您需要同时处理其他事情或者重构花费的时间比您最初想象的要多,那么拥有一个单独的分支可以让事情变得更容易。 另一个好处是,它使多个人可以更轻松地参与重构,并且您可以根据需要随时将内容签入分支。
I go with 1, make small changes when possible and check in often or else the merges become painful. Having a separate branch can make things easier if you need to work on other things at the same time or the refactoring takes more time than you originally thought. The other bonus is that it makes it easier for several people to take part in the re-factoring and you can check things in to the branch as often as you like.
对于发布时间间隔至少为 2 个月的情况,我建议采用以下策略。
当您开始接近发布时,创建一个发布分支。 发布分支应被视为这里请不要重构并且我是(几乎)功能完整的分支。 此时您应该开始集中精力在发布分支上稳定发布。 根据需要将发布分支中的任何缺陷修复合并回主干。 同时,主干被视为永久开放以进行重构。 此外,如果可行的话,请尝试在接近主要版本时减少重构,并在发布后的几天内加速重构。
如果您遵循持续发布策略(即每 1 到 2 周发布一次),则不应在单独的分支上分离重构和编码,除非您正在进行重大手术增强。 在这种手术增强情况下(每次间隔时间应不少于 3 个月),每当您打算执行合并时,请提前从计划中删除一个版本,使用其中一个周期进行版本合并和增加测试,保留您的手指交叉然后松开。
I would suggest the following strategy for a scenarios where time window between releases is at least 2 months.
When you start getting close to a release, create a release branch. Release branch should be treated as no refactoring here please and i am (almost) feature complete branch. It is at this point you should start focusing your effort on stabilising the release on the release branch. Merge back any defect fixes from the release branch onto the trunk as necessary. Meanwhile the trunk is treated as perpetually open for refactoring. Also if feasible try to reduce refactoring as you get closer to a major release and accelerate it in the days immediately after one.
In case you are following a continuous release strategy (ie. a release every 1 to 2 weeks), you should not separate refactoring and coding on separate branches, unless you are doing a major surgical enhancement. In such surgical enhancement situations (which should be spaced out no less than 3 months each), drop a release from your schedule in advance whenever you intend to perform a merge, use one of the cycles for the release merge and increased testing, keep your fingers crossed and then release.
更改必须是快速(因此您手下的更改不会太多)或局部(因此您只关心少数地方的更改)。
否则,合并的工作量可能与重构一样多。 作为一种算法,当太多事务失败并且必须重新启动时,乐观锁定根本不起作用。
从根本上来说,你不能允许一个公司的 20 名程序员每天都更改代码库中 50% 的方法的名称。 就此而言,如果多个人总是同时在同一位置进行重构,那么他们无论如何都只会撤销彼此的工作。
如果程序员花费大量时间手动监督合并,那么向经理提供一个通过改变任务定义和分配方式来提高生产力的机会。
此外,“重构整个系统以在各处使用工厂”也不是一项任务。 “重构这个接口及其实现以使用工厂”是一项任务。
Changes need to be either quick (so not too much changes under you) or else local (so you only care about changes in a small number of places).
Otherwise the merge can be just as much work as the refactor was. As an algorithm, optimistic locking simply doesn't work when too many transactions fail and must be restarted.
Fundamentally, you cannot allow a situation where 20 programmers in a company all change the names of 50% of the methods in the code base every day. And for that matter, if multiple people are always refactoring in the same places at the same time, then they're only undoing each other's work anyway.
If programmers are spending a lot of time manually supervising merges, then present to your managers an opportunity to increase productivity by changing the way tasks are defined and assigned.
Also, "refactor the whole system to use factories everywhere" is not a task. "Refactor this one interface and its implementations to use factories" is a task.
这就是优秀的分布式 VCS 的优势所在。 但我猜你已经致力于使用 SVN 了。
就我个人而言,我只是进行重构,然后尽快合并以避免冲突地狱。 这不是最高效的方法,但却是最不容易出错的方法。
我曾经有一个分支休眠了大约三周,因为该功能被“搁置”并且无法合并。 我刚刚在一个新分支中重新启动该功能,使用旧分支作为某些部分的参考。
This is where a good distributed VCS excels. But I am guessing you are committed to SVN already.
Personally, I just do the refactor and then merge as soon as possible to avoid the conflict hell. It is not the most productive method, but the least error prone.
I once had a branch that sat dormant for about 3 weeks because the feature was 'put on hold' and it was impossible to merge. I just started the feature over again in a new branch, using the old as reference for certain parts.