2

私は Web データベースを開発していますが、これはすでに約 12 の個別のインストールで使用されており、そのほとんどは私も管理しています。各インストールには、かなりのローカル構成とカスタマイズがあります。svn から mercurial に切り替えたばかりなので、その分散された性質を利用してローカルの変更を追跡したいと考えています。インストールされている各サーバーを独自のレポとしてセットアップしました (および .hg ディレクトリを提供しないように apache を構成しました)。

私の問題は、開発ツリーにもローカル構成が含まれていることです。バージョン管理されていない構成ファイルにすべてのビットを配置することは避けたいと考えています。では、マスター リポジトリとインストール済みのコピーにローカル構成が伝播されないようにするにはどうすればよいでしょうか。

例:バージョン管理と配布が必要な長い config.ini ファイルがあります。「クリーン」バージョンにはデータベース接続パラメーターのプレースホルダーが含まれており、インストールされたコピーのリポジトリーに開発サーバーのパスワードを入れたくありません。しかし、ときどき、伝播する必要のある変更 (新しいデフォルトなど) を行います。同様の状況にあるファイルがいくつかあります。

これまでのところ、mq をインストールして、ローカルの変更をパッチ (実際には、論理的に別々の変更セットを持つ 2 つのパッチ) に変換することが最善の方法です。通常の変更セットをローカルリポジトリにコミットするたびに、すべてのパッチをポップし、変更をコミットして、パッチを再適用する必要があります。マスター リポジトリにプッシュする準備ができたら、もう一度パッチをポップし、プッシュして、再適用する必要があります。これはすべて複雑で、エラーが発生しやすいものです。

私が見ることができる他の唯一の代替手段は、プッシュを忘れて変更セットをパッチとしてのみ伝播することですが、これはさらに悪い解決策のようです. 誰かがより良いセットアップを提案できますか? これがそれほど珍しい構成だとは想像できませんが、それについては何も見つかりませんでした。

編集:ここでの提案をフォローアップした後、名前付きブランチとリベースがシンプルで実行可能なソリューションを提供するという結論に達しました。私自身の回答の形で説明を追加しました。ご覧ください。

4

4 に答える 4

2

あなたのコメントから、これに対処するためのベスト プラクティスに既に精通しているように見えます: 構成テンプレートをバージョン管理し、実際の構成をバージョン管理しないでください。

しかし、その解決策に満足できない場合は、別の解決策を試すことができます。

Mercurial 2.1 ではPhasesの概念が導入されました。フェーズは、「secret」、「draft」、または「public」としてマークするチェンジセット メタデータです。通常、このメタデータは、Mercurial とその拡張機能によって、ユーザーが意識することなく自動的に使用および操作されます。

ただし、1234他のリポジトリにプッシュしたくない変更セットを作成した場合は、次のように手動でシークレットとしてマークすることでこれを強制できます。

hg phase --force --secret -r 1234

その後、別のリポジトリにプッシュしようとすると、次の警告が表示されて無視されます:

pushing to http://example.com/some/other/repository
searching for changes
no changes found (ignored 1 secret changesets)

このソリューションにより、次のことが可能になります。

  1. ローカル構成の変更のバージョン
  2. これらの変更が誤ってプッシュされないようにする
  3. ローカルの変更を、プルした他の変更とマージします

もちろん、大きな欠点は、この秘密の変更セットの上に行った変更をプッシュできないことです (秘密の変更セットをプッシュするため)。それらをプッシュする前に、そのような変更をリベースする必要があります。

于 2012-03-04T13:41:28.483 に答える
1

rebaseここでの提案をフォローアップした結果、名前付きブランチに加えて、シンプルで信頼性の高いソリューションが提供されるという結論に達しました。私はしばらくの間、次の方法を使用してきましたが、非常にうまく機能します。基本的に、ローカルの変更に関する履歴は、リベースで簡単に再配置できる名前付きのブランチに分けられます。

local構成情報にはブランチを使用します。すべてのリポジトリが Phases をサポートしたら、ローカル ブランチをマークしますsecret。しかし、この方法はそれがなくても機能します。localに依存しdefaultますが、デフォルトは に依存しないlocalため、独立して ( で) プッシュできますhg push -r default。仕組みは次のとおりです。

  1. 開発のメイン ラインがdefaultブランチにあるとします。(より多くのブランチを持つことができます。これは具体性のためです)。パスワードなどを含まないマスター (安定) リポジトリがあります。

    ---o--o--o   (default)
    
  2. デプロイされた (開発用ではない) クローンごとに、ブランチを作成し、localすべてのローカル状態をそこにコミットします。

    ...o--o--o   (default)
              \
               L--L    (local)
    
  3. アップストリームからの更新は常にデフォルトになります。local更新をプルするたびに、それらを(nは新しい更新のシーケンスです)にマージします。

    ...o--o--o--n--n    (default)
              \     \
               L--L--N     (local)
    

    ローカル ブランチは の進化を追跡しておりdefault、何か問題が発生した場合でも古い構成に戻すことができます。

  4. 開発サーバーでは、同じセットアップから始めます。つまり、local上記の構成設定を持つブランチです。これは決してプッシュされません。しかし、の先端でlocal、3 番目のブランチを作成しますdev。ここで新しい開発が行われます。

    ...o--o   (default)
           \
            L--L    (local)
                \
                 d--d--d     (dev)
    
  5. いくつかの機能をメイン リポジトリに公開する準備ができたら、まず、devブランチ全体を の先端にリベースしdefaultます。

    hg rebase --source "min(branch('dev'))" --dest default --detach
    

    前のツリーは次のようになります。

    ...o--o--d--d--d   (default)
           \
            L--L    (local)
    

    リベースされた変更セットは現在ブランチに属していdefaultます。--keepbranches(機能ブランチでは、rebase コマンドに追加してブランチ名を保持します)。新機能は に祖先がなくなり、ローカル リビジョンに沿ってドラッグすることなく、localで公開できます。( からにpush -r defaultマージしないでください。その逆のみです)。プッシュするときに言うのを忘れても問題ありません。新しいヘッドが追加されるため、プッシュは拒否されます。local default-r default

  6. 開発サーバーで、リベースさlocalれたリビジョンをプルしたかのようにマージします。

    ...o--o--d--d--d   (default)
           \        \
            L--L-----N    (local)
    
  7. の上に新しいdevブランチを作成し、local開発を続けることができるようになりました。

これには、バージョン管理され、構成されたセットアップで開発できる利点があります。パッチをいじる必要がないこと。以前の構成段階が履歴に残っていること (更新後に Web サーバーが機能しなくなった場合、構成済みのバージョンに戻すことができます)。変更を公開する準備ができたときに、一度だけリベースします。リベースとその後のマージは、リビジョンがローカル構成の変更と競合する場合に競合を引き起こす可能性があります。しかし、それが発生する場合は、マージ機能が解決に役立つときに発生する方がよいでしょう。

于 2012-04-03T07:30:57.327 に答える
1

バージョン管理されたテンプレートとバージョン管理されていないローカル コピーの問題が、テンプレートへの変更がローカル コピーに反映されないことである場合は、バージョン管理されていないテンプレートを使用するようにアプリを変更し、不足しているパラメーターに対してlocalconfig.iniバージョン管理されたものにフォールバックしてみてはどうでしょうか。config.iniこのようにして、新しいデフォルト パラメーターをアプリに追加しconfig.ini、アプリに反映させることができます。

于 2012-03-04T16:49:36.507 に答える
0

1 Mercurial have (コメントへのフォローアップ) 選択的 (文字列ベース) コミット - レコード拡張を参照

2バージョン管理されたパブリック ファイル内のローカルな変更は、MQ 拡張機能を使用して簡単に受け取ることができます (私は常にサイト構成に対して行っています)。MQ による頭痛の種

通常の変更セットをローカル リポジトリにコミットするたびに、すべてのパッチをポップし、変更をコミットして、パッチを再適用する必要があります。マスター リポジトリにプッシュする準備ができたら、もう一度パッチをポップし、プッシュして、再適用する必要があります。

これは、洗練されていないワークフローと (いくつかの) 誤解の結果です。MQ パッチなしでコミットする場合は、手動で行わないでください。commit のエイリアスを追加します。これは qop -all + commit であり、この新しいコマンドのみを使用します。また、プッシュするときは、MQ の状態を気にする必要はありません。WC 状態ではなく、リポジトリから変更セットをプッシュします。ローカル リポジトリは、コンテンツをチェックするプレコミット フックによってエイリアスなしで保護することもできます。

3 LocalBranches 拡張機能を試すことができます。ここでは、ローカルの変更がローカル ブランチ内に格納されます (そして、変更時にブランチをマージします)。MQ と比較して、この方法はより面倒であることがわかりました。

于 2012-03-04T15:57:02.777 に答える