如何在一个分支中重构而不会失去理智?

时间:2022-10-30 18:26:36

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).

我一直在重构我和其他人的代码。当我在分支而不是Trunk中工作时,这有时会导致一些非常痛苦的合并,特别是如果我不定期合并回Trunk(分支处的代码慢慢地从Trunc转移,当人们修改Trunk I时)必须手动弄清楚如何将其应用于分支)。

The solutions I know are either

我知道的解决方案也是

  1. Constantly merge to and from Trunk - reduces painful merges, but then why work in a branch at all?
  2. 不断地与Trunk合并 - 减少痛苦的合并,但那么为什么要在分支机构工作呢?

  3. 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.
  4. 每当你需要重构一些东西时,切换到Trunk,在那里进行重构并合并到你的分支 - 我不觉得这非常实用,因为每次重构的切换环境的实际成本是巨大的。

What do you do?

你是做什么?

8 个解决方案

#1


6  

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.

在那种情况下,为什么要在分支机构工作?因为你有更多的控制权(你可以停止合并到trunk中以稳定它以便释放,例如,不停止签入你的开发分支)。因为您可以围绕合并到/从中继进行高级别的验证,而不会影响到开发分支的签入速度。

#2


3  

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.

我选择1,尽可能做小的改动并经常检查,否则合并会变得很痛苦。如果您需要同时处理其他事情或者重构需要比您原先想象的更多时间,那么拥有一个单独的分支可以使事情变得更容易。另一个好处是它可以让几个人更容易参与重新分解,你可以随时检查分支机构的内容。

#3


2  

I would suggest the following strategy for a scenarios where time window between releases is at least 2 months.

对于发布版本之间的时间窗口至少为2个月的情况,我建议采用以下策略。

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.

如果您遵循连续释放策略(即每1至2周发布一次),则不应将重构和编码分开在不同的分支上,除非您正在进行重大的手术增强。在这种手术增强情况下(每个应该间隔不少于3个月),每当您打算执行合并时,请提前从您的日程表中删除,使用其中一个周期进行发布合并并增加测试,保持手指交叉然后释放。

#4


2  

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.

从根本上说,你不能允许公司中的20个程序员每天都改变代码库中50%方法的名称。就此而言,如果多个人总是同时在同一个地方进行重构,那么无论如何他们只是在取消彼此的工作。

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.

此外,“重构整个系统到处使用工厂”不是一项任务。 “重构这个接口及其实现以使用工厂”是一项任务。

#5


1  

This is where a good distributed VCS excels. But I am guessing you are committed to SVN already.

这是一个优秀的分布式VCS擅长的地方。但我猜你已经致力于SVN了。

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.

我曾经有一个分支处于休眠状态大约3周,因为该功能被“搁置”并且无法合并。我刚刚在一个新的分支中重新启动了该功能,使用旧的作为某些部分的参考。

#6


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.

如果你绝对需要分支,我会选择选项1.尝试合并尽可能小的更改并经常进行。

#7


1  

Commit early, commit often.

尽早承诺,经常承诺。

Or in this case... Merge early, merge often.

或者在这种情况下......早点合并,经常合并。

#8


1  

Continuous integration is the key... 1 small batch of changes at a time...

持续集成是关键......一次只做一小批改变......

#1


6  

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.

在那种情况下,为什么要在分支机构工作?因为你有更多的控制权(你可以停止合并到trunk中以稳定它以便释放,例如,不停止签入你的开发分支)。因为您可以围绕合并到/从中继进行高级别的验证,而不会影响到开发分支的签入速度。

#2


3  

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.

我选择1,尽可能做小的改动并经常检查,否则合并会变得很痛苦。如果您需要同时处理其他事情或者重构需要比您原先想象的更多时间,那么拥有一个单独的分支可以使事情变得更容易。另一个好处是它可以让几个人更容易参与重新分解,你可以随时检查分支机构的内容。

#3


2  

I would suggest the following strategy for a scenarios where time window between releases is at least 2 months.

对于发布版本之间的时间窗口至少为2个月的情况,我建议采用以下策略。

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.

如果您遵循连续释放策略(即每1至2周发布一次),则不应将重构和编码分开在不同的分支上,除非您正在进行重大的手术增强。在这种手术增强情况下(每个应该间隔不少于3个月),每当您打算执行合并时,请提前从您的日程表中删除,使用其中一个周期进行发布合并并增加测试,保持手指交叉然后释放。

#4


2  

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.

从根本上说,你不能允许公司中的20个程序员每天都改变代码库中50%方法的名称。就此而言,如果多个人总是同时在同一个地方进行重构,那么无论如何他们只是在取消彼此的工作。

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.

此外,“重构整个系统到处使用工厂”不是一项任务。 “重构这个接口及其实现以使用工厂”是一项任务。

#5


1  

This is where a good distributed VCS excels. But I am guessing you are committed to SVN already.

这是一个优秀的分布式VCS擅长的地方。但我猜你已经致力于SVN了。

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.

我曾经有一个分支处于休眠状态大约3周,因为该功能被“搁置”并且无法合并。我刚刚在一个新的分支中重新启动了该功能,使用旧的作为某些部分的参考。

#6


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.

如果你绝对需要分支,我会选择选项1.尝试合并尽可能小的更改并经常进行。

#7


1  

Commit early, commit often.

尽早承诺,经常承诺。

Or in this case... Merge early, merge often.

或者在这种情况下......早点合并,经常合并。

#8


1  

Continuous integration is the key... 1 small batch of changes at a time...

持续集成是关键......一次只做一小批改变......