ソース管理で構成ファイルをどのように扱いますか?


96

典型的なWebアプリがあり、ファイルの構成が何であるとしましょう。プロジェクトに取り組んでいるすべての開発者には、開発ボックスのバージョンが1つあります。開発バージョン、製品バージョン、ステージバージョンがあります。ソース管理でこれにどのように対処しますか?このファイルをまったくチェックインせず、別の名前でチェックインするか、まったく気の利いた何かをしますか?

回答:


69

私が過去にやったことは、ソース管理にチェックインされるデフォルトの設定ファイルを持つことです。次に、開発者ごとに独自のオーバーライド構成ファイルがあり、ソース管理から除外されます。アプリは最初にデフォルトをロードし、次にオーバーライドファイルが存在する場合はそれをロードし、オーバーライドからデフォルトファイルに優先して設定を使用します。

一般に、オーバーライドファイルは小さいほど良いですが、非常に非標準的な環境の開発者向けの設定を常に多く含めることができます。


24

構成コードであり、バージョン管理を行う必要があります。設定ファイルはユーザー名に基づいています。UNIX / MacとWindowsの両方でユーザーのログイン名にアクセスでき、これらがプロジェクトに固有である限り、問題ありません。環境でこれをオーバーライドすることもできますが、すべてバージョン管理する必要があります。

これにより、他のユーザーの構成を調べることもでき、ビルドやプラットフォームの問題を診断するのに役立ちます。


10
+1は絶対にその構成を強調するために、まだバージョン管理されなければならない
アレクサンダー・バード

また、何らかの理由でユーザー名が信頼できない場合は、オーバーライド構成ファイルの名前を1行だけで含む単一のファイルを作成できます。このように、そこにある非常に小さなバージョン管理されない(約10文字かそこらのように)。そして、READMEファイルは、そのファイルを作成する必要があることを説明できます。
Alexander Bird

構成はコードとは別にしておくべきだといつも思っています。私は、1つのリポジトリーに非常に多くの構成を必要とする場所で働いてきたため、Gitは構成ファイルに圧倒されます。設定はバージョン管理されるべきではないと言っているのではなく、Artifact Managerのような他の場所に属しています。構成はコードではなく、コードの設定です。
トーマス

構成ファイルには、バージョン管理すべきではないパスワードなどの機密情報が含まれている場合があります。または、すべての開発者に本番環境へのアクセスを許可しますか?「マスター構成」をバージョン管理し、特定の環境でそれをオーバーライドする方が良いと思います。
Christophe Weis

19

そのファイルをバージョン管理しないでください。テンプレートなどにバージョンを付けます。


2
私はこのアプローチを使用し、main.php.tmplを用意し、新しいコピーをチェックアウトするときはmain、phpにコピーします。誤ってコミットしないように、main.phpファイルを無視リストに追加します。
levhita 2008

10

私のチームは、環境ごとに異なるバージョンの構成ファイル(web.config.dev、web.config.test、web.config.prod)を保持しています。デプロイメントスクリプトは正しいバージョンをコピーし、名前をweb.configに変更します。このようにして、各環境の構成ファイルの完全なバージョン管理を行い、簡単にdiffなどを実行できます。


6

現在、たとえば次のように拡張子が追加された「テンプレート」設定ファイルがあります。

web.config.rename

ただし、重大な変更が変更された場合、この方法で問題が発生することがあります。


6

テンプレートアプローチの+1。

しかし、この質問にはGitというタグが付いているので、分散された代替案が思い浮かびます。ここでは、カスタマイズがプライベートテストブランチに保持されています。

A---B---C---D---           <- mainline (public)
     \       \
      B'------D'---        <- testing (private)

このスキームでは、メインラインには、機能するために最小限の調整を必要とする一般的な「テンプレート」設定ファイルが含まれています。

現在、開発者/テスターは設定ファイルを自分のコンテンツに合わせて調整し、これらの変更を1つのプライベートテストブランチ(B '= B +カスタマイズなど)でローカルにコミットするだけです。メインラインが進むたびに、簡単にテストにマージされてテストされ、D '(= D +マージされたバージョンのBのカスタマイズ)などのコミットコミットが行われます。

このスキームは、「テンプレート」設定ファイルが更新されたときに本当に効果的です。両側からの変更がマージされ、互換性がない場合、競合(またはテストの失敗)が発生する可能性が非常に高くなります。


ただし、開発者のテスターがメインラインにプッシュすると、テンプレートファイルに対する変更もプッシュされます。番号?
Nick Zalutskiy 2009

ニックのコメントに対する解決策がない限り、これは私が見ているものからは機能しません。または、問題を解決するために使用しているフローモデルを説明してください。
Alexander Bird、

ビルド時に必要な調整が行われるテンプレートアプローチに同意します。ただし、分岐トピックについて...複数のテンプレート(開発、テストなど)があり、開発者がコミットから変更を単に省略した場合はどうなりますか。絶対確実ではありませんが、協力して動作する可能性があります。
NickSuperb

5

私たちが使用するソリューションは、単一の構成ファイル(web.config / app.config)のみを使用することですが、すべての環境の設定を含むファイルに特別なセクションを追加します。

ありLOCAL、DEV、QA、PRODUCTIONのセクション、当社の設定ファイル(複数可)でその環境に関連する設定キーを含む各。

これをすべて機能させるのは、xxx.Environmentという名前のアセンブリです。これは、すべてのアプリケーション(winformsおよびwebforms)で参照され、動作している環境をアプリケーションに通知します。

xxx.Environmentアセンブリは、特定のマシンのmachine.configから1行の情報を読み取り、それがDEV、QAなどにあることを通知します。このエントリは、すべてのワークステーションとサーバーに存在します。

お役に立てれば。


1
環境(つまり、接続文字列)の違いがほんのわずかである場合、これは非常にうまく機能します
Eric Labashosky 2009

そして、何百人もの開発者がカスタマイズされた設定をそこに置いているわけではないと仮定します(それでも機能しますが、非常に面倒です)
Alexander Bird

5

私は常に、すべてのバージョンの構成ファイルをweb.configファイルと同じフォルダー内のソース管理に保持しています。

例えば

web.config
web.qa.config
web.staging.config
web.production.config

私はこの命名規則(web.config.productionやproduction.web.configではなく)を好みます。

  • ファイル名で並べ替えると、ファイルがまとめられます
  • ファイル拡張子で並べ替えると、ファイルが一緒に保持されます
  • ファイルが誤って本番環境にプッシュされた場合、IISが* .configファイルの提供を阻止するため、http経由でコンテンツを表示できません。

デフォルトの構成ファイルは、自分のマシンでローカルにアプリケーションを実行できるように構成する必要があります。

最も重要なこととして、これらのファイルは、フォーマットを含め、あらゆる面でほぼ100%同一である必要があります。インデントには、あるバージョンではタブを使用し、別のバージョンではスペースを使用しないでください。ファイルに対して差分ツールを実行して、ファイル間の違いを正確に確認できるはずです。ファイルの比較にはWinMergeを使用することを好みます。

ビルドプロセスでバイナリが作成されると、web.configをその環境に適した構成ファイルで上書きするタスクが存在するはずです。ファイルが圧縮されている場合は、関係のないファイルをそのビルドから削除する必要があります。


4

以前にテンプレート、つまりweb.dev.config、web.prod.configなどを使用しましたが、現在は「ファイルのオーバーライド」手法を使用しています。web.configファイルには設定の大部分が含まれていますが、外部ファイルには、db接続などの環境固有の値が含まれています。ポール・ウィルソンのブログの良い説明。

これにより、新しい値/属性を追加するときに痛みを引き起こす可能性がある構成ファイル間の重複の量が減少すると思います。


3

@Grantは正しいです。

私は100人近くの開発者とチームを組んでおり、設定ファイルはソース管理にチェックインされていません。各チェックアウトでプルされるリポジトリ内のファイルのバージョンがありますが、それらは変更されません。

それは私たちにとってかなりうまくいきました。


2

私はそれをバージョン管理しますが、他のサーバーに決してプッシュしません。運用サーバーで変更が必要な場合は、構成ファイルに直接変更を加えます。

きれいではないかもしれませんが、問題なく動作します。


2

チェックインされたプレーンバニラバージョンのapp / web.configは、すべての開発者マシンで機能するのに十分な汎用性があり、新しい設定の変更などで最新の状態に保つ必要があります。開発用の特定の設定セットが必要な場合/ test / production設定。GateKillerが述べたように、なんらかの命名規則を使用して、これらの設定で個別のファイルをチェックインしますが、ファイル拡張子を変更しないため、通常は「web.prod.config」を使用します。


2

バージョン管理にチェックインされたテンプレート構成ファイルを使用してから、自動ビルドのステップで、テンプレートファイルの特定のエントリを環境固有の設定に置き換えます。環境固有の設定は、バージョン管理下にある別のXMLファイルに保存されます。

自動ビルドではMSBuildを使用しているため、MSBuildコミュニティタスクの XmlUpdateタスクを使用して値を更新します。


2

長い間、私はbcwoodが行ったことを正確に行ってきました。web.dev.config、web.test.config、web.prod.configなどのコピーをソース管理下に保持し、さまざまな環境にデプロイするときに、ビルド/デプロイシステムが自動的に名前を変更します。ファイル間である程度の冗長性が得られますが(特に、そこに含まれるすべてのasp.netの要素がある場合)、一般的には非常にうまく機能します。また、チームの全員が変更を加えたときにすべてのファイルを更新することを忘れないようにする必要もあります。

ちなみに、ファイルの関連付けが壊れないように、末尾に「.config」を拡張子として残しておきます。

設定ファイルのローカル開発者バージョンに関しては、できるだけ同じローカル設定を使用するように最善を尽くしており、独自のバージョンを用意する必要はありません。それは常にすべての人に役立つとは限りません。その場合、人々は通常、必要に応じてローカルでそれを交換し、そこから移動します。あまり痛くないです。


1

このプロジェクトでは、接頭辞付きのファイルに構成が保存されており、ビルドシステムは現在のシステムのホスト名に基づいて適切な構成を取得します。これは比較的小さなチームでうまく機能し、新しい構成アイテムを追加する場合に、他の人のファイルに構成変更を適用できます。明らかに、これは無制限の数の開発者がいるオープンソースプロジェクトに対応することはできません。


1

ここで2つの問題があります。

  • まず、ソフトウェアに付属している構成ファイルを制御する必要があります。

    開発者がデボルブメント環境で同じファイルを使用している場合、マスター構成ファイルを変更するために不要なものをチェックインするのは簡単です。

    反対に、インストーラーに含まれている別の構成ファイルがある場合、新しい設定を追加するのを忘れたり、その中のコメントをデボルブメントのコメントと同期させないようにするのは非常に簡単です設定ファイル。

  • 次に、他の開発者が新しい構成設定を追加したときに、開発者が構成ファイルのコピーを最新に保つ必要があるという問題があります。ただし、データベース接続文字列などの一部の設定は、開発者ごとに異なります。

  • 質問/回答ではカバーされない3番目の問題があります。 ソフトウェアの新しいバージョンをインストールするときに、顧客が構成ファイルに加えた変更をどのようにマージしますか?

すべてのケースでうまく機能する優れたソリューションはまだ見ていません が、問題を大幅に軽減するいくつかの部分的なソリューション(必要に応じてさまざまな組み合わせで組み合わせることができる)を見てきました。

  • まず、メイン構成ファイルにある構成アイテムの数を減らします。

    顧客がマッピングを変更できるようにする必要がない場合は、Fluent NHibernate(またはその他の方法)を使用して構成をコードに移動します。

    同様に、過剰注入のセットアップについても同様です。

  • 可能であれば、構成ファイルを分割します。たとえば、別のファイルを使用して、Log4Netがログに記録するものを構成します。

  • 多数の構成ファイル間で項目を繰り返さないでください。たとえば、すべて同じマシンに4つのWebアプリケーションがインストールされている場合、各アプリケーションのweb.configファイルが指す全体的な構成ファイルを用意します。

    (デフォルトでは相対パスを使用するため、web.configファイルを変更する必要はほとんどありません)

  • 開発構成ファイルを処理して、出荷構成ファイルを取得します。

    これは、Xmlコメントにデフォルト値を設定することで行うことができます。これは、ビルドが行われたときに構成ファイルに設定されます。または、インストーラーの作成プロセスの一部として削除されるセクションがあります。

  • データベース接続文字列を1つだけでなく、開発者ごとに1つずつ用意します。

    たとえば、実行時に構成ファイルで最初に「database_ianr」(ianrはユーザー名またはマシン名)を探し、見つからない場合は「データベース」を探します。

    第2レベルの「eg -oracleまたは-sqlserver」を使用すると、開発者は両方のデータベースシステムにすばやくアクセスできます。

    もちろん、これは他の構成値に対しても実行できます。

    次に、「_ userName」で終わるすべての値を削除してから、構成ファイルを出荷できます。

ただし、結局のところ、あなたは「構成ファイルの所有者」であり、責任を持って上記またはその他の方法で構成ファイルを管理します。また、各発送の前に、お客様向けの構成ファイルを比較する必要があります。

思いやりのある人の必要性をこれほど短い問題で取り除くことはできません。


1

構成ファイル内のデータの機密性、または使用しているプログラミング言語、および他の多くの要因に依存する可能性があるため、すべてのケースで機能する単一のソリューションがあるとは思いません。しかし、すべての環境の構成ファイルをソース管理下に置くことが重要であると思うので、いつ変更されたか、誰が変更したかを常に知ることができます。そして彼らはそうするでしょう。

だからここに私がそれをする方法があります。これは通常nodejsプロジェクト用ですが、他のフレームワークや言語でも機能すると思います。

私が行うことはconfigs、プロジェクトのルートにディレクトリを作成し、そのディレクトリの下に、すべての環境用の複数のファイル(および場合によっては、各開発者の環境用の個別のファイル)を保持し、それらすべてをソース管理で追跡します。そして、コードが使用する実際のファイルconfigは、プロジェクトのルートにあります。これは追跡されない唯一のファイルです。だからこんな感じ

root
|
|- config (not tracked)
|
|- configs/ (all tracked)
    |- development
    |- staging
    |- live
    |- James

誰かがプロジェクトをチェックアウトすると、追跡対象外のconfigファイルで使用する設定ファイルをコピーし、自由に編集できますが、必要に応じて他の環境ファイルにコミットする前にこれらの変更をコピーする責任もあります。

サーバーでは、追跡されていないファイルは、単にその環境に対応する追跡されたファイルのコピー(または参照)にすることができます。JSでは、そのファイルを要求するための1行を指定できます。

このフローは、最初は少し複雑かもしれませんが、大きな利点があります。1.バックアップがなくても、サーバー上で構成ファイルが削除または変更されることを心配する必要はありません。2.開発者がカスタム構成を持っている場合も同様です。マシンと彼のマシンは、あなたがのための設定ファイルのdiffをすることができます任意の展開前に、何らかの理由で3の作動が停止するdevelopmentと、staging例えば、および見つからないか壊れて何があるかどうかを確認してください。


0

プロダクション構成ファイルをチェックインしたままにするだけです。ステージングや開発のためにファイルをソースから安全に取り出すときに、ファイルを変更するのは開発者の責任です。これは過去に私たちを焼いたので、私はそれを勧めません。


0

私は同じ問題に直面し、その解決策を見つけました。最初にすべてのファイルを中央リポジトリに追加しました(開発者も同様です)。

したがって、開発者がリポジトリからファイルをフェッチする場合、開発者設定もそこにあります。このファイルに加えられた変更を行う場合、Gitはこれらの変更を認識しません。この方法では、変更をリポジトリにプッシュ/コミットすることはできませんが、ローカルに留まります。

私はgitコマンドを使用してこれを解決しました:update-index --assume-unchanged。Gitが変更を無視する必要があるファイルを含むプロジェクトのプリビルドで実行されるbatファイルを作成しました。これが私がbatファイルに入れたコードです:

IF NOT EXIST %2%\.git GOTO NOGIT
set fileName=%1
set fileName=%fileName:\=/%
for /f "useback tokens=*" %%a in ('%fileName%') do set fileName=%%~a
set "gitUpdate=git update-index --assume-unchanged"
set parameter= "%gitUpdate% %fileName%"
echo %parameter% as parameter for git
"C:\Program Files (x86)\Git\bin\sh.exe" --login -i -c %parameter%
echo Make FIleBehaveLikeUnchangedForGit Done.
GOTO END
:NOGIT
echo no git here.
echo %2%
:END

私のプリビルドでは、たとえば、batファイルを呼び出します。

call "$(ProjectDir)\..\..\MakeFileBehaveLikeUnchangedForGit.bat" "$(ProjectDir)Web.config.developer" "$(SolutionDir)"

SOで、正しい構成ファイルをweb.config / app.configにコピーするbatファイルを見つけました。私はまた、このビルドファイルをプリビルドで呼び出します。このbatファイルのコードは次のとおりです。

@echo off
echo Comparing two files: %1 with %2
if not exist %1 goto File1NotFound
if not exist %2 goto File2NotFound
fc %1 %2 
if %ERRORLEVEL%==0 GOTO NoCopy
echo Files are not the same.  Copying %1 over %2
copy %1 %2 /y & goto END
:NoCopy
echo Files are the same.  Did nothing
goto END
:File1NotFound
echo %1 not found.
goto END
:File2NotFound
copy %1 %2 /y
goto END
:END
echo Done.

私のプリビルドでは、たとえば、batファイルを呼び出します。

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