SVNの使用の実用的な側面:外部

分散バージョン管理システム(Git、Mercurial、Bazaar)がますます人気を集めているという事実にもかかわらず、古き良きSubversionはまだ広く使用されています。 この記事では、実際にSVNリポジトリーで外部依存関係(svn:externals)を使用することの長所と短所を調べます。

svn:externalsの例を見てみましょう。 有名なPDFライブラリiTextなど、サードパーティのオープンソースコードを使用するプロジェクトがあるとします。 通常、このライブラリに必要なすべてのコードをリポジトリに完全にコピーします。 その後、iTextの更新がリリースされると、古いファイルを手動で新しいファイルに置き換えます。

svn:外部はより便利な方法を提供します。 リポジトリのフォルダーを選択し、このフォームでsvn:externalsプロパティを設定します( TortoiseSVNを使用してこれを行う方法 ):

  iText https://itext.svn.sourceforge.net/svnroot/itext/trunk 

最初のパラメーターは変更をダウンロードする場所を決定し、2番目のパラメーターは変更をダウンロードします。 これで、リポジトリから最新の更新を取得するたびに、iTextの現在のバージョンが自動的にダウンロードされます。 便利。

プロについて


svn:externalsを使用する利点を考慮してください。

重複を避ける

DRY (Do n't Repeat Yourself)の原則-品質の高いソフトウェア開発の礎石-は、ソースコード管理にまで及びます。 同じファイルが複数のリポジトリに複製されている場合-これはあまり良くありません。

たとえば、確立されたチームでは、原則として共通コードのベースが形成され、さまざまなプロジェクトで常に使用されます。 すべてのプロジェクトが1つの大きなリポジトリにあるとは限りません。 最も可能性が高い-別の。 この場合、svn:externalsなしでは、異なるリポジトリ間で同じファイルをコピーするだけでなく、変更があった場合はどこでも手動で更新することができます。

リポジトリ内のスペースを占有しないでください

前の段落の直接的な結果は、ソースコードが元のリポジトリにのみ保存され、そこから作業コピーにのみダウンロードすることです。 リポジトリの合計サイズに制限のある有料SVNホスティングを使用する場合、リポジトリのサイズは非常に重要です。

プロジェクトおよびモジュールの構造化が容易

「1プロジェクト<-> 1リポジトリ」というルールに従ってプロジェクトを分割することは理にかなっています。 このアプローチでは、svn:externalsを使用すると、依存プロジェクトの分離が簡単になります。

もちろん、同じリポジトリ内のすべてのプロジェクト/モジュールで作業できますが、このアプローチには欠点がないわけではありません。 たとえば、すべての開発者は、作業コピーに多くの不必要な変更をアップロードできます。 開発者がアクセスすべきでないプロジェクトへのアクセスを制限することはできません。 近くには無関係のプロジェクトがあります。 とにかく、すべてをヒープに保持することは適切なアプローチのようには見えません。

ただし、1つの大きなリポジトリで作業している場合は、svn:externalsも役立ちます。 例:リポジトリ内(トランク内)に次のフォルダー構造があるとします:/ Common / C#and / OurCustomer / Windows / HelloCSharp /。 HelloCSharpプロジェクトでCommon / C#のコードを使用する場合、次の3つの方法があります。
  1. 目的のコードをHelloCSharpにコピーします
  2. 相対パスを使用する
  3. たとえば、svn:externalsを使用してour_repository / trunk / Common / C#からHelloCSharp / Commonにコードをロードします。
最初の方法は明らかに悪いです-手作業と複製はしばしばエラーを引き起こします。
2番目は正常ですが、小さな欠陥があります。 たとえば、Common / C#フォルダーを転送する場合、HelloCSharpのすべての相対パスを変更する必要があります。 または-共有ファイルを見るには、リポジトリ内のフォルダを移動する必要があります。
SVNの3番目の方法:外観は最もイデオロギー的に正しいように見えます。 実際には、指定された場所に共通コードをロードするだけです。実際に参照するだけです。 SVN内の一種のシンボリックリンク。

リポジトリ内のオープンソースコードを使いやすくします。

最初の例で説明したもの。 ブースト全体をリポジトリにアップロードする場合-価値はありません。 この目的でsvn:externalsを使用する方が適切です。

短所について


プロは非常に説得力があるように見えますが、リポジトリでのsvn:externalsの広範な導入に急ぐことはありません。 svn:externalsがもたらす問題を評価しましょう:

遅い更新(svn update)

外部依存関係を使用する場合、以前の高速更新を忘れることがあります。 各依存関係は、アップグレード中に少なくとも1つの追加HTTP接続です。 外部リポジトリで何も変更されていない場合でも、待機します。 実際の作業では、更新時間が非常に顕著に増加しているため、問題は追加の接続だけに限定されないという感覚が得られます。

svn:外観は本当に遅いです。 少なくともSubversionの現在の実装では。

コードは単独で動作を停止する場合があります

この形式でsvn:externalsを使用する場合:

  iText https://itext.svn.sourceforge.net/svnroot/itext/trunk 

以前に実行したコードがまだ機能していることを保証することはできません。 外部リポジトリを変更すると、破損する可能性があります。 コードがコンパイルを停止したり、潜在的なエラーが表示されたりする場合がありますが、参加することはありません。

このアプローチを使用することはほとんどお勧めできません。 外部が同じリポジトリ内にある場合でも。 外部リポジトリを完全に制御できる場合でも。 このアプローチにより、リポジトリの履歴は変更されなくなります。 あるリビジョンにロールバックすると、svn:externalsを介してダウンロードされたコードがリビジョンの作成から経過した時間で変化する可能性があるため、予測できない結果が得られます。 以前は手間のかからないコードが単にコンパイルされない可能性が非常に高いです。

ただし、svn:externalsに終止符を打たないでください。この問題には解決策があります。次のように、外部リポジトリの特定のリビジョンを参照する必要があります。

  iText –r 247 https://itext.svn.sourceforge.net/svnroot/itext/trunk 

これで、このリビジョンのコードの特定のバージョンを常に取得できます。 更新を受信する場合、リビジョン番号を適切なものに更新し、更新をダウンロードします。 コードが以前と同様にコンパイルおよび動作することを確認します(テストを実行します)。 すべてが順調であれば、変更をsvn:externalsにコミットします。

参照しているサーバーが利用できない場合、アップグレードすることはできません。

外部サーバー(たとえば、itext.svn.sourceforge.net)が使用できない場合、新しいリビジョンまたは以前のリビジョンにアップグレードすることはできません(外部もそこで使用されている場合)。

参照しているサーバーが移動した場合-リポジトリを完全に変更する必要があります

もちろん、すべての古いリビジョンを操作可能なままにしておきたい場合は、現在のリビジョンの変更のみに制限することができます。 しかし、これはもちろん悲惨な道です。

この場合、リポジトリを完全に変更することはそれほど難しくありません。
  1. 「svnadmin dump」を使用してリポジトリをダンプします
  2. 結果のダンプで、同様のタイプのすべての行を見つけます。
      V 66
     iText –r 247 https://itext.svn.sourceforge.net/svnroot/itext/trunk
    
    小道具エンド 
  3. それらのリポジトリへのパスを置き換えて、最初の行の数値を更新します-これは、プロパティの説明のバイト数です。次に例を示します。
      V 123
     iText -r 155 http://new_server.com/svnroot/itext/trunk/
     iTextSharp -r 155 http://new_server.com/svnroot/itextsharp/trunk/
    
    小道具エンド 
    ここでは、明確にするために、数Vの計算方法を明確にするために2行目を追加しました。
  4. 古いリポジトリを削除し、「svnadmin load」を使用して新しいダンプをロールアップします
リンク先のサーバーが他の何かのためにSubversionを変更したか、単に動作を停止した場合-すべてがなくなります

どちらの場合も、非常に否定的な結果を伴います-リポジトリは完全に機能しなくなります。

リビジョンへの更新が機能しなくなる場合があります

例:リポジトリにはiTextフォルダーが完全にあります。 次に、1つの賢い記事を読んだ後、代わりにsvn:externalsを実装することにしました。 私たちはそれを成功裏に実装し、機能し、誰もが幸せです。 ただし、現在のリビジョンから以前のリビジョンにロールバックする場合、機能しません。

これは、svn:externalsインストールがロールバックされるときに、ターゲットフォルダー(iText)が物理的に削除されないという事実によるものです。 また、リポジトリ内の通常の追跡フォルダーに置き換える必要がある場合、SVNの現在のバージョンでは解決できない競合が発生します。

この場合、解決策は1つしかありません。ゼロリビジョンから正しいリビジョンまで完全にチェックアウトすることです。

別のバージョン管理システムに正しく移行できない

SVNリポジトリからリポジトリに、たとえばGitやMercurialにコードを転送することにした場合、svn:externalsは深刻な障害になります。 解決策は3つあります:まったく検討しないか、この問題を無視して発生時に転送するか(この場合、古いリビジョンは機能しません)、またはsvn:externalsを完全に削除します。

最後の道は厄介ですが、結果は価値があります-どこにでもインポートできる完全に独立したリポジトリを取得します。 svnを取り除く方法:externalsは特に将来の記事のトピックです。

おわりに


svn:externalsを使用するかどうか-誰もが自分で決定します。 最初は外部の依存関係なしで作業しましたが、プロジェクトをいくつかのリポジトリに分解するときに、svn:externalsを積極的に使用し始めましたが、時間が経つにつれて、欠点が利点を上回ることがわかりました。 最終的に、私たちは通常Mercurialに移行することを決定しました。そのために、svn:externalsを完全に取り除く必要がありました。

そして最後に、svn:externalsを使用するためのいくつかのヒント:

Source: https://habr.com/ru/post/J109291/


All Articles