すべての開発がブランチ上にあるときにリファクタリングする方法は?


24

私の会社では、すべての開発(バグ修正と新機能)は別々のブランチで行われています。完了したら、QAに送信し、QAがそのブランチでテストします。QAが青信号を出したら、メインブランチにマージします。これには、1日から1年かかることがあります。

ブランチでリファクタリングを絞り込もうとすると、どれくらいの期間「アウト」されるかわからないので、マージして元に戻すと多くの競合が発生する可能性があります。

たとえば、作業中の機能がこの関数を頻繁に使用しているため、関数の名前を変更したいとします。名前が実際には目的に合わないことがわかりました(これも単なる例です)。そこで、この関数のすべての使用法を見つけて、それらをすべて新しい名前に変更すると、すべてが完全に機能するため、QAに送信します。

その間、新しい開発が行われており、名前が変更された関数は、メインから分岐されているブランチのいずれにも存在しません。私の問題が再び統合されると、それらはすべて壊れてしまいます。

これに対処する方法はありますか?

経営陣がリファクタリングのみの問題を承認するようなことはないので、他の作業に絞り込まなければなりません。mainで直接開発することはできません。なぜなら、すべての変更はQAを通過する必要があり、mainを壊したジャークになりたくないので、彼は少しの非本質的なリファクタリングを行うことができるからです。


どのバージョン管理を使用していますか?DVCSと集中型サーバーモデルにはさまざまなアプローチがあります。さらに、開発ブランチは何から離されていますか?機能ブランチが受け入れられた場合、他の開発ブランチはどのように変更を取得しますか?

2
余談ですが、現在の分岐構造の図は非常に役立ちます。リファクタリングの難しさの問題の根本原因の一部は、従来とは異なる分岐ポリシー(1つの例については、programmers.stackexchange.com / questions / 210360を参照)が原因である可能性があります。また、vance.com / steve / perforce / Branching_Strategies.htmlを読んで、いくつかのアイデアと背景を取得することをお勧めします(主要な参照ポイントとなるこの質問に答えることができる場合)。

1
最後の段落で要約します-ビジネスが価値を認識しない場合、主要なリファクタリングを進める方法はありません。テストチームと協力してタイムラインを解決する必要があります。(私はあなたのQAは、(彼らは上かつらや口紅を入れて、そうでない何かのふりを)実際のQAチームがあなたの邪魔になっていない、どのようなリファクタリングにあなたを伝えることになるドラッグで本当にテストしている疑いがある。)
mattnz

1
@mattnz:その通りです。彼らは本当のQAチームではありません。彼らは主に顧客サポートです。彼らの多くの責任は開発チームに戻されるべきだと思います。なぜなら彼らは私たちが彼らに投げかけるすべてを扱うことができないからです。しかし、それは管理上の問題であり、まだ勝てない戦いです。
mpen

3
あなたは私の発掘を見逃した。テスト!= QA。QAは品質を監督し、ビジネス成果の改善を目指しています。テストでは、欠陥を見つけて欠陥がないことを証明します。
mattnz

回答:


12

この環境でリファクタリングを困難にするために、いくつかの問題が混在しています。これには、非技術的な問題がいくつか混ざっています(「しかし、それは管理上の問題であり、まだ勝てない戦いです」)。

最初に確認する問題は、長時間実行されるブランチです。これらのブランチは、開発者の視点の外で変更を追跡するのが困難です。これに対処するには:

  • コードが完成したら-もう一度やり直します(必要に応じてカスタマーサポートに調べてもらいます)が、それをすぐに開発にマージして、それに依存する他の変更をピックアップし、競合する変更を早期に特定できるようにします過程の中で。
  • 何らかの理由で、リファクタリングの進行中にブランチが長時間実行されるようになった場合、stableからブランチにマージして変更とリファクタリングを取得することをお勧めします。多くの場合、これにより、機能ブランチから安定ブランチへのマージ時の競合や驚きが最小限に抑えられます。
  • すべての統合テストは、機能ではなくリリースで実行する必要があります。この環境では、機能がシステムに完全に統合されている場合とされていない場合があります。機能の健全性チェックを単独で行うことは可能ですが、リリース時に問題を特定することはできません。
  • コードの完了からマージ(開発と呼ぼう-マスター/安定/リリースからの分岐には、最新の開発変更が反映されないという独自の問題があります)が長すぎてはなりません。長く待つほど、失われる知識が増え、コードが他のコード行と統合されるのが難しくなります。

これにまつわるもう1つの問題は、上記のポイントでほのめかしたのは、ブランチの役割が時間とともに変化することです。開発者がコミットする開発ブランチとして開始され、次にテスト領域(アプリケーション全体で意味のあるテストがここで行われていますか?)になり、その後安定版にマージされます(そしておそらくリリースされます)もう一度テストしましたか?)。

機能の開始から終了までの時間を短くすると、リファクタリングを他のブランチで簡単に選択できるようになります。

開発者に環境全体を取得するように勧めます。ちょっと変わった変更を行うだけで、興味深い開発者環境を実現できます。チェリーピッキングには用途がありますが、それが変更をブランチにプルするデフォルトモードであることが気になる場合があります。

リファクタリングは、理想的には絶えず行われるものであり、ダウンタイムが少しある場合は常に行われます。ブランチ、簡単なリファクタリングを行い、ユニットテストを実行してすべてがまだ機能していることを確認し(そのユニットをテストしましたリファクタリングした変更を自分のブランチにプルするために、他の開発者に情報を渡します。

開発者がコードの品質を所有することは重要です。機能の方向は外部からのものであり、時間の割り当ては多くの場合私たちのものではありませんが、コードの品質は誇りを持ち時間を作るために必要なものです。

技術的負債に対処するための時間を割り当てるための探求では、次の質問が役立つことがあります。

また、リファクタリングに最も作業が必要なコードの領域を特定するのに役立つソナーなどのツールを参照することもできます。技術的負債のプラグインは、コードベースに時間をかけて債務の累積手伝っポイントに使用することができるものです。

多くの場合、技術的な負債を処理するためのROIは、開発チームからの機能とバグ修正のためのより速いターンアラウンドタイムであることを指摘する必要があります。


テストは基本的に3つの時点で実行されます。問題が修正されたと主張されると(すべての要件を満たし、重大な問題がないことを確認するため)、再びデフォルトに統合される(統合テスト)とき、およびビルドを行うとき(選択されたすべてのチェリーとの統合問題/最終確認)。非常に特定のクライアントでSaaSを運用している環境では、チェリーピッキングが必要だと思います。これらのリンクを見てみましょう。ポインタをありがとう!編集:実稼働環境で問題がないことを確認するために、実際にはもう1つのルックオーバーがあります。
mpen

3

通常、リファクタリングされたバージョンを、現在と同じ「並列」で、つまり同じコードベースで開発していますが、コアアプリケーションからは参照していません。そして、新しいソリューションが完成してテストされると、実際のリファクタリングを開始します。

例1. Thingがあると仮定します。関数、インターフェイス、モジュール、その他何でも可能です。そして、リファクタリングしたいです。同じコードベースでThing2を作成していますが、これはThingのリファクタリングバージョンです。それが完了してテストされたら、Thingを参照するすべてのものをリファクタリングし、Thing2に置き換えます。通常、このステップには比較的短い時間がかかります。

実際のリファクタリングがチームを混乱させることなく同期を維持するのに時間がかかりすぎる場合、私は関連するすべての機能を利用し、それらを並行してリファクタリングしています。

例2.新しいレンダリングバックエンドがあります。これは古いもののリファクタリングバージョンです。ただし、古いレンダリングフロントエンドとの互換性はありません。したがって、フロントエンドをリファクタリングする必要があります。そして再び:同じコードベースで。すべてが完了したら、フロントエンドインスタンスのクラスを変更するだけです。理想的には、1つの短いコミットが必要です。

はい、再帰的に、すべてを並行して行う必要があるという結論に達する可能性があります。しかし、これは通常、コードベースのカップリングが多すぎるか、変化が速すぎるときに発生します。

最後に、新しいコードが統合されて正常に機能するようになったら、古い機能をコードベースから削除し、新しい機能の名前を変更して古い名前を取得することができます。

一般的に、新しい機能を並行して準備し、1つの小さなステップでそれらを使用するように切り替えることが考えられます。

ジョン・カーマックは、この(または少なくとも類似の)アプローチを使用しています。おそらく彼のブログの投稿で、より適切に説明されています:(リンク)


これは良いアプローチです。私は今、この質問を本当に引き起こしたものを思い出そうとしています ...並列化に非常に適しているとは思いません。または、そうだった場合、このアプローチがコードベースで多くの断片化を引き起こすことを懸念しています。物事を行う「古い方法」と物事を行う「新しい方法」があり、古いものは氷河のペースで置き換えられていますが、開発者は本質的に2つ(またはそれ以上)のシステムを知る必要があるため、頭痛の種です。
mpen

1

実際には要件側にあるのに、技術側では困難に見えるかもしれません。

開発が異なるブランチの異なる要件に向けられているのは、本当に難しいことです。チームのマネージャーとアーキテクトは、さまざまなビジネスニーズが共存できるようにする決定を下すべきです。

ZBBプロセスとCo-Devは、すべての開発者からの適切な入力で適切な決定を行った後、「妥協」します。あとで考えることなく、必要なものを実装できます。

ZBBはZero-based budgetingの略です。Co-Devと言うことは、並列プログラミングで働いている人をほとんど意味していません。


2
「ZBB」と「Co-Dev」とは何ですか?
gnat

ZBB - en.wikipedia.org/wiki/Zero-based_budgeting。Co-Devと言うことは、並列プログラミングで働いている人をほとんど意味していません。
ヨシダハリ

1

問題は、あなたがブランチで過度に長く働いているように思えます。競合のコストは、全員がブランチにとどまる期間とともに指数関数的に増加するため、非常に長い競合では、リファクタリングを行う機会がほとんどありません。


0

問題は、使用しているブランチモデルです。ブランチ上で開発することができ、QAの準備が完了したら、ブランチは「統合トランク」または「テスト」と呼ばれることもある「中間トランク」にマージされます。次の機能を開発するとき、代わりにこの中間トランクから分岐できます。

このモデルを使用すると、さまざまなブランチで複数の機能を並行して開発し、それらをすべて統合ブランチにマージしてQAに送信し、リリースの単一トランクを維持することもできます(認証時にメイントランクに受け取ったコードベースQAをマージします) )

ただし、QAに配信された変更は大幅な変更なしで渡されることを前提としています-変更の半分を削除する指示とともにQAコードが戻ってきた場合、元に戻す必要がありますが、それが起こらない場合は開発がよりスムーズになります。つまり、基本的には、現在のコード(現在のトランク)ではなく、メインラインコード(QAに渡されたコードをマージした後のトランク)から新機能のブランチを取っているため、以前のリリースのコードベースに対しては開発されていません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.