Visual Studioで1年間の開発を統合するための戦略


32

私は、2016年全体で新しい開発をメインブランチから分離することを主張するクライアントがいます。他の3〜4チームがさまざまな能力でアプリケーションに取り組んでいます。多数の大きな変更が行われました(依存性注入の実行方法の切り替え、ReSharperによるコードのクリーンアップなど)。mainを新しいdevブランチにマージして、変更をチェーンにプッシュする準備をするようになりました。

私の最初のマージプルで、TFSは競合解決を伴う〜6500ファイルを報告しました。これらのいくつかは簡単になりますが、それらのいくつかははるかに困難になります(具体的には、javascript、apiコントローラー、およびこれらのコントローラーをサポートするサービスの一部)。

これを私にとって簡単にするアプローチがありますか?

明確にするために、途中で何度もこのアプローチに多くの懸念を表明しました。クライアントはこれに関する困難を認識していました。彼らはQAスタッフ(4人の開発者に1人のテスター、自動テストなし、ほとんど回帰テストなし)を選択したため、ブランチの必要性を減らすためにメインブランチの変更からブランチを隔離することを主張しました他の場所で行われている変更について知るためのテスター。

ここでの大きな問題の1つは、アンギュラーバージョンと他のサードパーティソフトウェアのアップグレードです。残念ながら、すべてのピースを元に戻すまで、このソリューションを構築する良い方法を思いつきません。


63
いや。1年間積極的に開発された2つの独立したブランチがあります。マージはうまくいきません。
17年

2
チームが行った変更の範囲はどのくらいですか?これらの変更を特定し、現在のマスターコードベースに手動で再適用する方が効率的です。
-kdgregory

2
2015年または2016年の全体ですか?2015年が2年だったら、それは2倍の悪さを意味します。
デビッドは、モニカを復活させる

1
クライアントのために行っている作業がバージョン管理システムの別のブランチにある場合、なぜクライアントは気にしますか?
Ixrec

17
何をするにせよ、毎時請求していることを確認してください。
ショーンマクサムシング

回答:


37

この不幸な状況に陥ることなく、あなたの新しい開発をメインブランチから分離しておく簡単な方法があったでしょう:トランクからの変更は毎日 devブランチマージされるべきでした。(あなたのクライアントは本当に近視眼的で、いつかあなたのブランチをメインラインに戻す必要があるとは予想できませんでしたか?)

とにかく、最善のアプローチは、私見が最初に起こったことをやり直そうとすることです:

  • ブランチが作成された後の1日目のメインラインの変更のセマンティクスを識別します。可能な限り、現在のコードベースに適用してください。「ローカルな変更」であれば、それは簡単なはずです。広く使われているクラスの名前を変更するような「クロスカッティングリファクタリング」であれば、現在のコードベースに意味的に同等の方法で適用します。その年の間に、「あなたの」ブランチでコードベースの矛盾する横断的な変更が行われなかったことを願っています。
  • 結果をテストします(このタスクに適したテストスイートが必要だと言いましたか)。テストで明らかになったすべてのバグを修正する
  • 2日目、3日目など、メインラインの変更に対してこのプロセスを繰り返します。

これは、チームがバージョン管理の古典的なルール(「コンパイル可能なテスト済みの状態のみをコミットする」および「早期かつ頻繁にチェックインする」)を厳守する場合に機能する可能性があります。

365回の繰り返し(または幸運で週末の変更に作業をバンドルできる場合は250回)後、ほぼ完了します(統合期間中にメインラインに発生する変更の数を追加する必要があるため) )。最後のステップは、更新されたdevブランチを再びトランクにマージすることです(したがって、トランクの履歴を失うことはありません)。技術的には影響を受けるファイルの置き換えに過ぎないため、これは簡単なはずです。

そして、はい、私は真剣です、おそらくこれへの近道はありません。「毎日の部分」は時々小さすぎるかもしれないことが判明するかもしれませんが、私はこれを期待しないでしょう、私はそれが毎日の部分が大きすぎると判明する可能性が高いと思います。クライアントがこれに対して本当に良い支払いをし、これが彼にとって非常に高価であり、彼が失敗から学ぶことを願っています。

切り替えた側でもこれを試すことができることを付け加えます-ブランチからの変更を小さな部分でメインラインに再統合します。これは、devブランチで変更がトランクよりもはるかに少ない場合、または現在トランクの一部ではない新しいソースファイルでほとんどの変更が行われた場合に簡単になる可能性があります。これは、機能を製品A(devブランチ)からやや異なる製品B(トランクの現在の状態)に「移植」するものとして見ることができます。しかし、大部分の横断的なリファクタリングがメインラインで行われ、それらが新しいコードに影響する場合(6500のマージの衝突は、この証拠のようです)、最初に説明した方法の方が簡単かもしれません。


9
再統合中にトランクの開発を継続している場合は、まずトランクの先端を分岐し、そこから開発することをお勧めします。それ以外の場合は、過去と未来を同時に効果的にマージしています。しかし、私は当然、時空の不連続性についてはDoc Brownに任せます。
レーダーボブ

1
@radarbob:最初に説明したように、OPがdevからtrunkに統合された場合にのみ意味がありますが、彼がtrunkからdevにマージすることを決定した場合には意味がありません。OPが毎日トランクから開発ブランチに変更を転送する場合(過去365日の変更から開始)、トランクでの開発が継続しても問題ありません。彼は現在に到達するまでこの戦術を続ける必要があります(1日以内にこれらの3-4チームの変更を1日で統合およびテストできると仮定)。
Doc Brown

引用:「スイッチサイドでもこれを試すことができることを付け加える必要があります-毎日のバンドルのブランチからメインラインへの変更を再統合します。」変化の統合が矛盾する「調和共振歪み」の潜在的なカスケードを感じます。
レーダーボブ

これは良いアドバイスです。編集を参照して、ここでいくつかのことを解決してください。
-user258451

1
@ user258451:では、トランクと新しいdevブランチに異なるQAチームがいて、お互いに話をしたくなかったのですか?グレートスコット:-((
Doc Brown

14

マージのその段階では、自動化されたマージはプロセスを過度に複雑にするだけだと思います。私は1年以上分岐しているブランチで同様の問題を抱えており、私が持っている最も効果的な方法は次のことをすることです:

  • 元の結合されていない状態のコピーを取ります
  • マージされていないものと最新のものの違い
  • 一般的な要素を分類する
    • たとえば、すべての関数名を変更してから、パラメーターを変更するなど。
    • 標準が変更された場合、差分の空白を無視します。そうしないと、スペースをカウントするのに多くの時間を無駄にします
  • 最初にコア機能に焦点を当てる

最終的にコンパイラの警告と差分はあなたの親友になります。マージされていない差分を使用して、何が違うのかを正確に確認し、そのまま続行してください。あなたが助けるために使用できるさまざまなツールがあるかもしれませんが、どれが最善かを見つけるのはあなた次第です。

キーは、続けることです。

編集:

警告の言葉ですが、このアプローチは、ブランチ間のマージの証拠とマージされていないブランチの履歴を失うため、バージョン管理履歴が「破損」することを意味します。

「ジャック・エイドリー」と「17 of 26」のコメントに感謝


1
このアプローチの主な問題は、バージョン管理システムに残っている変更の記録を破壊することです。
ジャックエイドリー

基本的に、マージ中に同じ変更をすべて2回行うことにより、変更のログが保持されます。開発中に行われた順序ではなく、マージで行われた順序になります。理想的ではありませんが、何もないよりはましです。さらに、バージョン管理で保持されていれば、元のマージされていない状態のままです。
エルドリックアイアンローズ

変更のログはありますが、ブランチごとに変更がマージされたという歴史的な証拠はありません。これはTFSでは大きな問題になります。TFSでは、ブランチ間でマージするときに選択できるマージされていないチェンジセットのみを提供します。
17年

@ 17of26いくつかの変更の記録を復元できることに同意しますが、26/17はこの記録が完全または正確ではないということは正しいです。このアプローチは、現在の悪い状況を考えると、この記録の損失を許容できる妥協点とするのに十分簡単かもしれません。
ジャックエイドリー

1
@ジャックエイドリー私はそれがかなり問題であることは間違いなく同意するので、反映するために私の答えに少し追加しました。大丈夫ですか?
エルドリックアイアンローズ

8

数年前、ブランチを分離するという同じ要件を持つクライアントがいました。でした。

ブランチをマージしませんでした。彼らには独自のバージョンがありました。基本的に1つのメイントランクとブランチではなく2つの主要なトランクがあったため、変更に対して追加料金を請求しました。

トランクに戻ろうとしましたが、2週間後、具体的なメリットがないまま何時間も燃えていたため、その努力を放棄することにしました。

そのため、マージして戻さないでください。今後は、必要に応じて重要な修正をそのクライアントブランチにマージし、機能強化はそのクライアントに特別に課される1回限りの支払いとなります。


この戦略は、異なる開発ラインが異なるクライアントをターゲットにしている場合にのみ実行可能です。または、製品が関係するユースケースで、2つの異なる製品ラインを非統合的に並行して使用できる場合。私の理解では、OPは、新しい開発ラインがトランクを使用しているクライアントと同じクライアントをターゲットにしている状況について説明しています。
Doc Brown

1

面白くはありませんが、どれだけ苦痛を感じるかは、変化の性質と、それがどれほど孤立しているかによって異なります。

実際のマージを行う前に、可能な限りリファクタリングしてブランチを収束させることをお勧めします。

マージツールは、テキストの違いのみを調べ、コードをまったく理解しないため、一種の馬鹿げたものです。メインブランチがアプリケーション全体で使用されるクラスの名前を変更し、機能ブランチが新しいコードで古い名前を使用する場合、マージツールは、新しいコードでクラス名も変更する必要があることを理解しません。ただし、ブランチBでリファクタリングを実行して、ブランチAのようにクラスの名前を変更すると、古いコードと新しいコードの両方で機能し、マージがスムーズに進みます。

次に、開発ブランチの変更がどの程度ローカライズされているかを調べる必要があります。機能ブランチの変更がいくつかの領域にローカライズされている場合、影響を受けないコードを収束する必要はなく、メインブランチからコピーして上書きするだけです。

両方のブランチで重要な変更が行われたコードの領域では、コードを慎重に検査し、書き換え方法を決定する必要があります。

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