1

私は亀のsvnを使用しています。しかし、私は一般的にsvnにはかなり慣れていません。ただし、gitの経験はあります。

ドキュメントではそれは言う

ブランチを再統合する

この方法は、Subversion ブックで説明されている機能ブランチを作成した場合に対応します。すべてのトランクの変更は、週ごとにフィーチャー ブランチに移植されました。これでフィーチャーが完成し、トランクにマージし直します。

私が理解している限りでは、機能ブランチの通常のワークフローは、機能ブランチを作成し、その上で開発を行い、トランク ブランチのバグ修正からリビジョンの範囲を頻繁にマージすることです。機能が完了したら、トランクの変更の最終的なマージを行い、ブランチをトランクに再統合します。

だから私はいくつかの質問があります:

  1. このワークフローは正しいですか
  2. 機能ブランチを再統合する前にトランク ブランチからの変更をマージしないとどうなりますか
  3. 完全に更新されたフィーチャー ブランチからトランク ブランチに通常のマージを実行するとどうなりますか
  4. なぜこれがそれほど複雑なのか、svn は git よりもユーザーフレンドリーであることを意図していますが、特にマージでは、機能ブランチにマージするリビジョンを指定する必要があり、さまざまなマージオプションから選択することは、同等の git 機能よりもはるかに複雑に見えます(私は会社で svn を使用する必要があります。他の開発者が使用しているため、彼らは分岐を行いません)、私が何か間違ったことをしていない限り
4

2 に答える 2

8

最初に、マージがどのように機能し、ほとんどすべてのバージョン管理システムで機能するかについての簡単なレッスンです。

標準の Merge は3 方向のマージです。ここでは、2 つのバージョンを 2 つのバージョンの最後の共通の祖先と比較しています。たとえば、トランクから分岐します。ブランチの前のトランクのバージョンは、最後の共通の祖先です。

目的は、一方のストリームの変更と他方のストリームの変更を確認できるようにすることです。(ストリームは、特定のブランチまたはトランクである可能性があります)。たとえば、トランクからブランチにマージする場合、特定のブランチの変更をトランクのそれらの行で上書きしないようにしたいと考えています。

最後の共通の祖先と比較すると、その分岐点以降にトランクで発生した変更のみを確認できます。

これは、以前のマージからさかのぼるときに問題を引き起こします。たとえば、フィーチャー ブランチが完成したので、すべてのフィーチャーの変更をトランクに戻したいとします。トランクの変更をすべてブランチにマージしたため、これは問題です。つまり、ブランチのストリームは、ブランチに変更を加えたことを示しており、これらはトランクにマージする必要があります。しかし、これらの変更はすでにトランクにあります。この問題を処理するには、双方向のマージを強制できます。この場合、2 つの別々のストリームのヘッドを互いに比較し、1 つのストリームから別のストリームにすべての違いをコピーするだけです。


Subversion がマージを処理する方法:

まず、Subversion はチェリー ピック マージが大好きです。Subversion では、マージするリビジョンを指定できます。たとえば、ブランチがあり、バグを見つけてブランチで修正しました。バグ修正を含む特定のリビジョンまたはリビジョンのセットをマージできるようになりました。Subversion でチェリー ピックすると、3 方向のマージが行われますが、トランクまたはブランチのすべての変更ではなく、特定のチェリー ピックバージョンで表される変更のみが考慮されます。

実際、Subversion は、チェリー ピック リビジョンを指定しなくても、ほぼ常にチェリー ピック マージを行います。Subversion は、svn:mergeinfoプロパティを介してどのリビジョンがマージされたかを追跡します。リビジョン 100 でブランチを作成し、トランクの変更をブランチにマージしているとします。トランクの最後のリビジョンは現在リビジョン 150 です。Subversion は、リビジョン 100 (ただし、バージョン 100 は含まれません) からリビジョン 150 までのトランクのすべてのバージョンのチェリー ピックを行っていると見なします。ブランチ (私のトランクの最後の変更が現在 175 であるとしましょう)、Subversion は(150 を含まない) 以降のトランクの変更をリビジョン 175 からチェリー ピックします。

マージにチェリー ピック リビジョンを指定すると、ブランチとトランクの間を問題なく行き来できることに注意してください。機能ブランチからトランクにマージする場合、機能を実装した機能ブランチのリビジョンを指定し、トランクからのマージの結果である機能ブランチの変更をスキップできます。

問題は、Subversion にチェリー ピッキングを処理させた場合にのみ発生します。トランクからブランチにマージすると、Subversion はブランチにあるトランクのリビジョンを追跡します。しかし、Subversion には、フィーチャー ブランチのどのリビジョンがトランク マージの結果であったかを知る方法がありません。

したがって、機能ブランチをトランクにマージすると、Subversion はマージされていないすべてのリビジョン (トランクからブランチへのマージの結果であるリビジョンを含む) を考慮し、これらすべてのリビジョンをトランクにマージしようとします。

これを処理するために、Subversion には再統合マージと呼ばれる特別なマージがあります。トランクの最後の変更セットをブランチにマージしてから、ブランチをトランクにマージするときに、トランクとブランチを同一にしたいと考えています。したがって、Subversion は双方向のマージを行い、トランクとブランチを一致させたいと考えています。

Subversion の古いバージョンでは、コマンドの--reintegrationパラメーターを使用して、この双方向マージを行うことを手動で指定する必要がありました。svn merge

Subversion のマージ トラッキングは、機能ブランチの再利用に関する興味深い問題にもつながります。トランクからブランチへの最後の一連のマージを行うとしましょう。トランクの最後のリビジョンと Subversion の最後のリビジョンはリビジョン 100 でした。トランクからの変更をブランチにマージすると、ブランチにリビジョン 101 が作成されます。そのブランチのsvn:mergeinfoプロパティは、トランクのみのブランチからリビジョン 100 までのすべての変更をマージしたことを示しています。

ここで、再統合マージを実行し、変更をコミットして、トランクにリビジョン 102 を作成します。

ここで、トランク (リビジョン 103 としましょう) でさらに作業を行い、それらの変更をフィーチャー ブランチにマージしたいと考えています。

トランクから機能ブランチにマージした最後のリビジョンは何ですか? を見るとsvn:mergeinfo、リビジョン 100 であることがわかります。トランクからブランチへの前回のマージ以降、トランクには 2 つの新しいリビジョンがあり、まだ機能ブランチにマージされていません: リビジョン 102 とリビジョン 103.

そのため、Subversion は厳選して、リビジョン 102 とリビジョン 103 に含まれる変更をフィーチャー ブランチにマージしようとしますしかし待ってください... リビジョン 102 は、すべての機能ブランチの変更がトランクにマージされていることです! これらの機能の変更を機能ブランチに再適用します!

これを処理するには 2 つの方法があります: 方法 1:再統合マージを実行したら、そのフィーチャー ブランチを二度と使用しないでください。消して。尼僧院に閉じ込めてください。二度とその名を口にするな。そのフィーチャー ブランチがもう一度必要な場合は、トランクから新しいフィーチャー ブランチを作成する必要があります。

もう 1 つの方法はsvn:mergeinfo、トランクのリビジョン 102 が既に機能ブランチにマージされていることを Subversion に知らせるために、機能ブランチを変更することです。--record-only次のパラメータを使用してこれを行うことができます。

$ svn co $REPO/branches/feature/myproj
$ cd myproj
$ svn merge --record-only -r102 $REPO/trunk/myproj

おわかりのように、この手動の作業はすべて、そのスイッチをいつ使用するかを知り、再統合--reintegrationマージを行うときに何が起こるかを理解することで、混乱を引き起こしました。したがって、Subversion の新しいバージョン (リビジョン 1.8 以降と思われます) では、これを処理しようとしています。

Subversion 1.8 をクライアントとして使用している場合は、--reintegrationパラメーターを指定する必要はありません。Subversion は、通常の 3 者間マージを実行しているか、再統合マージを実行しているかをプログラムで判断し、それに応じて動作します。

Subversion がreintegration mergeと見なすことをしようとして、すべてのトランク リビジョンをフィーチャー ブランチにまだマージしていない場合、Subversion は警告を発し、マージを許可しません。再統合マージを行った後に機能ブランチを再利用すると、Subversion はこれを検出し、再統合後にブランチの再利用の問題を自動的に処理すると想定されます。(完全に機能しない場合もあります。ただし、Subversion では、再統合マージ後に機能ブランチを再利用することはできませんが、エラーが発生する可能性があり、手動で--record-onlyマージを行う必要がある場合があります。)


では、Subversion では、ワークフローをどのように行うべきでしょうか?

各バグと機能を独自のブランチに配置する必要がある Git とは異なり、そのバグ修正または機能を複数のブランチにマージする必要が少なく、ほとんどすべての作業をトランク (または好きなブランチ) からすぐに実行できます。ほとんどの Subversion ショップでは、分岐は候補リリースに対してのみ行われます。つまり、私はリリースをしようとしています。そのリリースのためにブランチします。一部の開発者はリリースに取り組んでおり、他の開発者はトランクの作業を続けています。

トランクでバグが見つかった場合は、トランクで修正でき、そのバグが修正されたリビジョンまたはリビジョンのセットをリリース ブランチにマージできます。または、トランクで修正する必要がある機能ブランチのバグを見つけた場合は、機能ブランチでそのバグを修正し、そのリビジョンまたはリビジョン セットをトランクにマージできます。

シンプルでわかりやすく、実装も簡単です。

これは、機能のために分岐できないという意味ではありません。実際、そうしなければならないこともあります。将来的に実装される機能を想像してみてください。これらの変更をトランクに加えたくありません。その場合、フィーチャー ブランチを作成し、トランクの変更を定期的にそのフィーチャー ブランチにマージします。その機能をトランクにマージするときに問題が発生する可能性があることに注意してください。何が起こっているのかを理解する限り。問題ありません。

また、機能やバグごとに膨大な数のブランチを作成して独り占めしたい場合は、それも可能です。ただし、Subversion 1.8 を使用することをお勧めします。

于 2014-04-02T16:36:18.690 に答える
0
  1. 多かれ少なかれ

  2. トランクから機能ブランチへの頻繁なマージのポイントは、それが断片的であることです: 小さくて扱いやすい. 対立が生じたとき、それらはあなたの心に新たな変化をもたらすことで解決できます。再統合する前にトランクから機能ブランチに変更をマージしなければ、「悪い」ことは何も起こりません。すべての変更を一度にマージする必要があるため、多くの競合が発生する可能性があります。、競合を引き起こしているコードの部分さえ覚えていない可能性があり、そのコードを再学習し、競合の解決により多くの時間を費やすことになります。トランクとフィーチャー ブランチが毎日同期されている場合、同期を実行して競合を解消するために 1 日あたり 5 分間追加するだけで十分です。機能ブランチの最後までそのままにしておくと、すべての競合を一度に解決するのに 1 日か 2 日かかる場合があります。

  3. ブランチの再統合とリビジョンの範囲のマージを参照してください。リビジョンの範囲のマージと SVN での再統合の違いは何ですか? --reintegrate with svn merge back to trunk を使用しないことの結果

  4. SVN は git よりもユーザーフレンドリーです。集中管理されており、TortoiseSVN の形で優れた Windows GUI を備えています。TortoiseSVN の最新バージョンでは、「再統合」オプションが削除されました。マージするリビジョンにチェックマークを付けると、この情報が SVN に保存されるため、次回はどのリビジョンが既にチェックインされているかなどを視覚的に簡単に確認できます。

于 2014-04-02T13:58:24.167 に答える