17

2つのリポジトリに分割する必要があるプロジェクトがあります。1つは一般的なモデルのセットで、もう1つはそれらのモデルに基づくシミュレーションと追加のコードです。最終的には、同じモデルセットを使用した複数のシミュレーションが存在する可能性があるため、それらを別々のリポジトリに配置することは明確な要件です。明らかな解決策は、シミュレーションのサブモジュールとして共通モデルを使用することです。

残念ながら、2つのリポジトリは非常に高度に結合されます。人々は非常に頻繁に共通のモデルに何かを追加し、すぐにそれをシミュレーションで使用します。これは、シミュレーションのリポジトリの統合プロセスで多くの頭痛の種になると思います。シミュレーションで多くの開発者からの変更をマージするには、インテグレーターは共通モデルサブモジュールで並列マージを実行する必要があります。一方、サブモジュールを使用することも不可欠です。シミュレーションでは、使用する必要のある一般的なモデルのバージョンを実際に知る必要があります。

このプロジェクトはかなりの数の人々によって行われています。ほとんどの開発者は、gitについて非常に大雑把な知識しか持っていません。ファイルを追加し、コミットし、オリジンからプルします。できれば、開発者と安定したブランチを持っています。インテグレーターは当然、かなり多くのことを学びましたが、サブモジュールを含むものはすべて彼にとって確かに新しいものです。追加ボーナス:私は1か月の休暇を取るところなので、火を消すことができなくなります。結果として、ワークフローを台無しにするのを本当に難しくし、人々の以前のワークフローとの違いを最小限に抑えるための多くのインセンティブがあります。

だから、私の質問は次のとおりです:これにサブモジュールを使用することをお勧めすることを後悔するつもりですか?(もっと良いアイデアはありますか?)人々にどのような間違いを期待できるので、事前に警告することができますか?覚えておくべき良いワークフロー戦略はありますか?

編集:私はちょうどgit slaveに出くわしました、これはこの文脈でも一見の価値があるかもしれません。そのウェブサイトにあるものを超えて能力/制限の良い評価をまだ与えることができません。

4

2 に答える 2

15

これを横切って起こっている他の誰かのためのいくつかのメモ!

ルーキーが犯そうとしている最大の間違いは、サブモジュールの更新を行った後、サブモジュールでHEADを切り離してコミットすることです。フックからの強い警告でこれに対抗しようと思います。

次に大きいのは、サブモジュールを必要とするチェックアウトを実行した後、サブモジュールの更新を実行できないことです。繰り返しますが、フックはこれをチェックして警告することができます。

開発プロセスに関しては、このセットアップにより、サブモジュールに優れたテストインフラストラクチャを用意することがはるかに重要になります。これにより、可能であれば、親で作業することなくサブモジュールで作業でき、問題を完全に回避できます。

最終的に使用するフックからサンプルコードを投稿し、1か月後に(多すぎないことを願って)本当のホラーストーリーをフォローアップします。

編集:

これがフックの最初のドラフトです。これは急いでいる仕事であることを忘れないでください、そして私に気楽に行ってください!

親リポジトリ:

マージ後およびチェックアウト後、サブモジュールが同期していない場合はユーザーに警告します。(ポストマージは、特に早送りマージ、オリジンからのプルに含まれています)また、サブモジュールのポストチェックアウトフックもサブモジュール更新を実行するときにそれを行いますが、ブランチをチェックアウトする必要があることに注意してください。より多くのリマインダーが楽しい。

#!/bin/bash
if git submodule status | grep '^+' > /dev/null; then
    echo "WARNING: common model submodule now out of sync. You probably want to run" 1>&2
    echo "         git submodule update, then make sure to check out an appropriate branch" 1>&2
    echo "         in the submodule." 1>&2
fi

コミット後の場合、サブモジュールの変更がある場合は、コミットに含めるのを忘れている可能性があることをユーザーに警告します。この高度に結合されたケースでは、これは非常に良い推測です。ユーザーがシミュレーションモデルと一般モデルを別々に変更する可能性はほとんどありません。

#!/bin/bash
if git submodule status | grep '^+' > /dev/null; then
    echo "WARNING: common model submodule has changes. If the commit you just made depends" 1>&2
    echo "         on those changes, you must run git add on the submodule, and then run" 1>&2
    echo "         git commit --amend to fix your commit." 1>&2
fi

また、サブモジュールでは、チェックアウト後のフックを使用して、HEADが切り離されていることを強く警告します。

#!/bin/bash

get_ppid() {
    ps --no-headers -o ppid $1
}

# Check to see if this checkout is part of a submodule update
# git submodule calls git checkout, which calls this script, so we need to
# check the grandparent process.
if ps --no-headers -o command $(get_ppid $(get_ppid $$)) | grep 'submodule update' &> /dev/null; then
    if ! git symbolic-ref HEAD &> /dev/null; then
        echo "WARNING: common model submodule entering detached HEAD state. If you don't know" 1>&2
        echo "         what this means, and you just ran 'git submodule update', you probably" 1>&2
        echo "         want to check out an appropriate branch in the submodule repository." 1>&2
        echo
        # escape the asterisk from SO's syntax highlighting (it sees C comments)
        branches=($(git for-each-ref --format='%(objectname) %(refname:short)' refs/heads/\* | grep ^$(git rev-parse HEAD) | cut -d\  -f2))
        case ${#branches} in
            0 )
                ;;
            1 ) 
                echo "Branch '${branches[0]}' is at HEAD"
                ;;
            * )
                echo "The following branches are at HEAD: ${branches[@]}"
                ;;
        esac
    fi
    echo
fi

また、デタッチされたHEADで行われたコミットを単純に中止するためのpre-commitフックを追加しています(リベースでない限り)。私は、古典的な「私のコミットがすべて消えた」というパニックに陥った苦情を受け取るのをかなり恐れています。--no-verify自分が何をしているのかを知っていれば、いつでもそれをバイパスすることができます。

于 2010-09-15T20:07:58.603 に答える
8

サブモジュールは、関連するさまざまなコンポーネントの正確なリビジョンを参照するための良い選択です。「サブモジュールの本質
」で詳しく説明したように、最初にサブモジュールをコミットすれば、どのサブモジュールも更新できます(次に、親リポジトリに移動してコミットします)。

ただし、密結合のモジュールの場合は、次のことを避けようとします。

「これは、シミュレーションのリポジトリの統合プロセスで多くの頭痛の種になると思います」。

中央統合プロセスが効率的に機能しているとは思いません。新しい早送りの進化のみを記録する必要があります。
そのためには、何かをプッシュしたいユーザーは、最初にプルして、すでにプッシュされている新しい変更に加えて変更をリベースする必要があります。
開発者は、競合を解決したり、リベース中に対処しなければならない変更の原因を同僚に尋ねたりする傾向があります。

これ(プル、リベース、プッシュ)は、次の理由で常に可能であるとは限りません。

  • 「高度な」(あまり基本的ではない)関連するGit操作(および現在のワークフローと完全に同一ではないワークフロー)
  • 関係する作業(他の貢献者からの進化を考慮に入れる)
  • 環境設定(追加の環境を設定することは、そのリベースを作成することであることが望ましい場合がありますが、これも「それほど基本的ではありません」

しかし、それでも私が試みる方向です。

(...しかし、1か月の休暇の直前ではないかもしれません;)
では、もう一度、誰が1か月の休暇を取ります?!その概念をこれまで聞いたことがない)

于 2010-09-14T22:50:42.067 に答える