web-dev-qa-db-ja.com

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

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

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

これを簡単に行うことができるアプローチはありますか?

明確にするために、私は途中で何度もこのアプローチに大きな懸念を表明しました。クライアントはこれに関する困難を認識し、認識しています。彼らはQAスタッフ(4人の開発者に1人のテスター、自動テストなし、わずかなリグレッションテスト)を利用しないことを選択したため、メインブランチの変更からブランチを分離する必要があると主張して、ブランチをメインブランチの変更から隔離すると主張しました。他の場所で行われた変更について知るテスター。

ここでの大きな問題の1つは、angularバージョンおよび他のサードパーティ製ソフトウェアのいくつかへのアップグレードです。残念ながら、すべてのピースが揃うまで、このソリューションを構築するための良い方法を思いつきません。元の場所に戻します。

31
user258451

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

とにかく、私たちが最初に何が起こっているべきかをやり直そうとする私見が最善のアプローチです。

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

これは、チームがバージョン管理の従来の規則に厳密に準拠している場合に機能する可能性があります(「コンパイル可能でテスト済みの状態のみをコミット」し、「早期かつ頻繁にチェックインする」)。

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

そして、はい、私は真剣です、おそらくこれへの近道はありません。 「1日の割合」が小さすぎることもあるかもしれませんが、これは期待できません。1日の割合が多すぎる可能性が高いと思います。あなたのクライアントがあなたにこれのために本当によく払ってくれることを望みます、そしてこれは彼にとって彼の失敗から学ぶほど高額であることを願っています。

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

37
Doc Brown

マージのその段階では、自動マージはプロセスを非常に複雑にするだけかもしれないと私は言うでしょう。私は1年以上分岐した支店で同様の問題を抱えていましたが、私が最も効果的な方法は次のことです。

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

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

鍵は続けることです。

編集:

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

「Jack Aidley」と「17 of 26」からのコメントに感謝します

14
Erdrik Ironrose

数年前、ブランチを分離しておくという同じ要件を持つクライアントがいました。だから私たちはしました。

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

トランクにマージしようと試みましたが、2週間後、何時間にもわたって明白な利点がなく燃え尽きたため、その取り組みを放棄することにしました。

したがって、マージしないでください。今後は、必要に応じてそのクライアントブランチに重要な修正をマージします。拡張機能は、そのクライアントに特別に課金されます。

8
Jon Raynor

それは楽しいことではありませんが、それがどれほど痛みを伴うかは、変更の性質と、それらがどれほど孤立しているかによって異なります。

できるだけリファクタリングしてブランチを収束しようとすることをお勧めしますbefore実際のマージを行います。

マージツールは、テキストの違いのみを確認し、コードをまったく理解しないので、ちょっとばかげています。 mainブランチがアプリケーション全体で使用されるクラスの名前を変更し、featureブランチがいくつかの新しいコードで古い名前を使用する場合、マージツールはクラス名も新しいコードで変更する必要があることを理解しません。しかし、ブランチBでリファクタリングを行って、ブランチAのようにクラスの名前を変更すると、古いコードと新しいコードの両方で機能し、マージはスムーズに行われます。

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

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

1
JacquesB