Gitサブモジュールを使ったMoodle開発環境

このページでは、外部プラグインを使用してMoodleインスタンスの開発環境を設定する方法について説明します。時間の経過とともにプラグインの数はそのように増加するかもしれず、もはや開発者によって手動で管理されることはできません。予防策がないと、さまざまな問題が発生する可能性があります。

  • クローンリポジトリに見つからないプラグイン
  • 既存のリポジトリのバージョンが異なる(サイトを更新しようとすると致命的なエラーが発生する可能性がある)
  • めちゃくちゃGitは除外

このガイドでは、以下の設定を達成するためにGitサブモジュールを使用する方法を学びます。

開発環境の仕組み

注:拡張モジュールmod_mylittleextension は、テスト目的でのみ作成された偽のプラグインです。

Gitサブモジュールを使用することで、リポジトリのすべての拡張機能を他のプロジェクトと簡単に同期させることができます。すべてのリポジトリはいわゆるスーパープロジェクトリポジトリに基づいており、開発者のプロジェクトは「ローカル」リポジトリと呼ばれることもあります。 Gitによるスーパープロジェクトとコアの変更を維持することに興味がある人は誰でもGITでMoodle Production Serverを訪問することができます

注意:このガイドでは基本的なGitコマンドとGitサブモジュールのインストール/メンテナンス方法については説明しません。これらのトピックがカバーされているところでGit for Administratorsを読んだことを前提としています。スーパープロジェクトは、Gitサブモジュールを介していくつかのプラグインがすでにインストールされているMoodleリポジトリと見なされます。

スーパープロジェクトのクローン作成

最初に、スーパープロジェクトが複製されたときに引き起こされるイベントの簡単な説明。 Gitサブモジュールにはいくつかありますが、それは明白ではないので非常に驚くべきことです。 注:作業を続ける前に、 Gitサブモジュールを使用して提供された拡張機能をインストールおよび保守する方法について理解していることを確認してください。

プラグインmod_mylittleextension (MLEは偽のプラグインです)がスーパープロジェクトにインストールされており、これらの変更がコミットされているとします。

$ cd / path / to / your / superproject
$ gitサブモジュールadd / local / repositories / mle / mod / mylittleextension
$ git commit -a -m "新しいモジュールMLEがインストールされました"

開発者は、スーパープロジェクトのクローンを作成するために、次のコマンドを入力する必要があります(おそらくリモートデバイスから)。

$ cd / path / to / local /ディレクトリ
$ git clone <ソース> moodle
$ cdムードル
$ gitサブモジュールの更新--init --recursive
パス 'mod / mylittleextension'に登録されたサブモジュール 'mod / mylittleextension'(/ local / repositories / mle)
'mod / mylittleextension'にクローニングしています...
行った。
サブモジュールパス 'mod / mylittleextension':チェックアウト '89d9eae3d5142474d8452128e8df5720d89012cd'
$ cd mod / mylittleextension
mod / mylittleextension $ gitブランチ-av
*(ブランチなし)89d9eae初期コミット
  master 89d9eae初期コミット
  リモート/ origin / HEAD  - > origin / master
  remotes / origin / dev 3a2d487最初のコミット
  remotes / origin / master 89d9eae初期コミット

新しいメインリポジトリは自動的に新しい拡張子を認識しますが、初期化されないため、サブモジュールのディレクトリは最初は空になります。サブモジュールを初期化するために、開発者はgit submodule update --init --recursiveを実行する必要があります。 --recursiveオプションは、Gitが入れ子になったサブモジュールをたどることを意味します(この例では必須ではありません)。

初期化後、サブモジュールのリポジトリは分離HEAD状態になります。これは、Gitがスーパープロジェクトから次のデータを受け取るという事実によります。

 *ソースURL
 *ローカルパス
 * HEAD参照(ハッシュ)

より良い理解のために、この図を見てください。

点線:スーパープロジェクトから取得した情報ですが、すでにローカルに保存されています(pullによって)

つまり、 git submodule update --initは最初にソースURLのクローンをパスに入れ 、次に参照をチェックアウトして、サブモジュールを分離HEAD状態のままにします。あなたとあなたの開発者は、あなたのサブモジュールに対するHEADの参照のどんな変更もメインリポジトリによって気づかれることになることを心に留めておく必要があります。これはまた、HEADのハッシュ参照が変わらない限り、誰でも気付かれずにブランチを切り替えることができることを意味します。例えばブランチマスターのチェックアウトはメインリポジトリでは気付かれませんが、 devのチェックアウトは以下のようになります。

mod / mylittleextension $ gitチェックアウトマスター
mod / mylittleextension $ gitブランチ-av
*マスター89d9eae初期コミット
  リモート/ origin / HEAD  - > origin / master
  remotes / origin / dev 3a2d487最初のコミット
  remotes / origin / master 89d9eae初期コミット
$ cd ../ ..
$ gitステータス
#ブランチマスター
コミットするもの(作業ディレクトリをクリーン)
$ cd mod / mylittleextension
mod / mylittleextension $ gitチェックアウト開発者
ブランチ開発者は、リモートブランチ開発者を起点から追跡するようにセットアップしました。
新しいブランチ 'dev'に切り替えました
mod / mylittleextension $ cd ../ ..
$ gitステータス
#ブランチマスター
#変更がコミット用にステージングされていません。
#(コミットされる内容を更新するには "git add <file> ..."を使用してください)
#(作業ディレクトリの変更を破棄するには "git checkout  -  <file> ..."を使用してください)
#
#変更:mod / mylittleextension(新しいコミット)
#
コミットに変更を加えない( "git add"や "git commit -a"を使う)

サブモジュールを初期化するための短いコマンドがありますが、結果は上記と同じになります。クローンの後にmoodleディレクトリを変更してgitサブモジュール更新--initを使用する代わりに、 - recursiveオプションを指定してgit cloneを使用することもできます。

$ cd / path / to / new / location
$ git clone  - 再帰的な<ソース> moodle

つまり、 git cloneコマンドで--recursiveオプションを忘れた場合は、 gitサブモジュールupdate --initを使用することができます。

スーパープロジェクトを介してサブモジュールをアップグレードする

我々は今、外部プラグインはそれ自身のリポジトリによってのみ更新され、カスタマイズは必要ないと仮定します。スーパープロジェクトのサブモジュールのメンテナンスのトピックについての詳細は、 Gitサブモジュール使った貢献された拡張機能のインストールとメンテナンスをご覧ください。

プルとアップグレード

サブプロジェクトがスーパープロジェクト内で更新された場合は、開発者は注意する必要があります。 git pullはサブモジュールを一度にアップグレードしないので追加のコマンドが必要です。これがgit pullのようなものです。

$ cd / path / to / local / repository
$ git pull
remote:オブジェクト数を数えます:5、完了しました。
remote:オブジェクトの圧縮:100%(3/3)、完了
リモート:合計3(デルタ2)、再利用0(デルタ0)
オブジェクトの開梱:100%(3/3)、完了
/ local / repositories / super /から
   b547f6c..7f0c348 master  - >原点/マスター
サブモジュールmod / mylittleextensionの取り出し
remote:オブジェクトを数える:7、終わった。
リモート:オブジェクトの圧縮:100%(5/5)、完了。
リモート:合計6(デルタ0)、再利用0(デルタ0)
オブジェクトの開梱:100%(6/6)、完了
/ local / repositories / mleから
   3a2d487..5e0e66a dev  - > origin / dev
   89d9eae..5e0e66a master  - >起源/マスター
b547f6c..7f0c348を更新中
早送り
 mod / mylittleextension | 2 +  - 
 1ファイル変更、1挿入(+)、1削除( - )
$ cd mod / mylittleextension
mod / mylittleextension $ gitブランチ-av
*(ブランチなし)89d9eae初期コミット
  dev 3a2d487 [の後ろ1]最初のコミット
  マスター89d9eae [2の後ろ]初期コミット
  remotes / origin / master 5e0e66aセカンドコミット
  remotes / origin / dev 5e0e66aセカンドコミット

ご覧のとおり、 git pullはサブモジュールリポジトリ内でgit fetch 起動しますが、それ以外は何もしません。したがって、開発者は後でサブモジュールを更新する必要があります。

$ cd / path / to / local / repository
$ gitサブモジュールの更新
サブモジュールパス 'mod / mylittleextension': '5e0e66aa787f4ebe9f61a940969a6e94abf01a1e'をチェックアウトしました

図:カスタマイズなしの更新

ソースリポジトリからアップグレードするためのワークフロー

既知の問題点

gitサブモジュールのアップグレードはあなたのメインリポジトリのコミットによって与えられた参照をチェックアウトするので、あなたのサブモジュールのリポジトリは再び分離されたHEAD状態に変わります。このコマンドは、各サブモジュールのパス内の参照をgitでチェックアウトするのと同じです。つまり、ディレクトリに入って手動でチェックアウトを実行しようとすると、競合によってチェックアウトが中止されます。そのため、サブモジュールの更新による問題を防ぐために、サブモジュールのリポジトリはクリーンである必要があります。

この問題の特別なケースは、サブモジュールの参照が起源によって知られていないスーパープロジェクトを複製しようとすると起こります。サブモジュールのディレクトリは空白のままにして(チェックアウトするものがないので)、手動でこの問題を解決する必要があります(例えば、スーパープロジェクトのサブモジュールリポジトリをリモートとして追加する)。状況は、あなたは確かに、取得したくありません。

カスタマイズされたプラグインのアップグレード

図:推奨ワークフロー

通常のワークフローでは、外部のプラグインに触れないので、サブモジュールを変更する必要はまったくありません。しかし、もしあなたがそれらを変更たいのなら、どうでしょう。場合によっては、サブモジュールがあなた自身のプラグインであるか、あるいは拡張子がどういうわけか不十分ですが、元の貢献者はあなたのpull requestをマージしたくありません。

前のセクションからわかるように、 gitサブモジュールの更新は特定の参照をチェックアウトしようとします。したがって、この参照は元の場所に存在する必要があります。そうしないと、それらを更新する際に問題が発生します。もしあなたがエクステンションの貢献者ではないのであれば、これらのリポジトリをフォークする必要があります。推奨されるワークフローは次のようになります。

カスタマイズされたプラグインを使った推奨ワークフロー

あなたの開発者はあなたのforkしたプラグインを更新する責任があります。そのため、元の変更をフォークされたコードにマージし、必要に応じて競合を解決する必要があります。あなたのスーパープロジェクトはフォークからのみ引っ張ります。最初のスーパープロジェクトを設定する場合は、フォークからすべての更新を取得するので、元のリポジトリにまったく接続する必要はありません。そのため、エクステンションのオリジナルのリモートを追加する代わりに、フォークのみを追加することができます(追加した後は、プラグインの最初のコミットの前にgit remote rename origin forkを使用できます)。

新しいサブモジュールを設定する

拡張機能をまだインストールしていない場合は、後で誤解を避けるためにリポジトリを追加して名前を変更することができます。スーパープロジェクトのマシンで、以下のコマンドを実行してください。

$ cd / path / to / moodle
$ gitサブモジュールadd <source:fork> mod / mylittleextension
'mod / mylittleextension'にクローニングしています...
行った。
$ cd mod / mylittleextension
mod / mylittleextension $ gitリモートリネームオリジンフォーク
mod / mylittleextension $ gitブランチ-avv
* master 5e0e66a [フォーク/ master]セカンドコミット
  リモート/フォーク/ HEAD  - >フォーク/マスター
  remotes / fork / dev 5e0e66aセカンドコミット
  リモート/フォーク/マスター5e0e66aセカンドコミット
mod / mylittleextension $ cd ../ ..
$ git commit -a -m "新しい拡張機能" MLE "がインストールされました"
[master adecc96]新しい拡張機能「MLE」がインストールされました
 2ファイルが変更され、4挿入(+)
 作成モード100644 .gitmodules
 作成モード160000 mod / mylittleextension

あなたの開発者はgit clonegit pullを使ってあなたの新しいサブモジュールを手に入れ、同様にリモートの名前を変更することができます。さらに、元のリモートから更新を取得し、リモートリポジトリを手動で追加する必要があります。あなたの開発者のマシン上でマシンタイプを入力してください(Gitからの出力メッセージは省略されます):

cd / path / to / local / repository
$ git pull
$ gitサブモジュールの更新--init
$ cd mod / mylittleextension
mod / mylittleextension $ gitリモートリネームオリジンフォーク
mod / mylittleextension $ gitリモートでオリジンを追加<source:origin>
mod / mylittleextension $ gitフェッチ元

これであなたの開発者はブランチを追加し、コードを編集し、コミットしそしてあなたのフォークに貢献することができます。そのトピックに関する詳細は次のセクションの後に続きます。

既存のサブモジュールに対する変更

サブモジュールがすでにインストールされていて、スーパープロジェクトのクローンが作成されている場合は、 .gitmodulesファイルを編集する必要があります。サブモジュールのパスURLが保存されているので( 参照はコミットに保存されています)、手動でファイルを編集することができます。しかし、その目的のためにGitコマンドを使うこともできます。スーパープロジェクトのマシンタイプで(Gitからの出力メッセージは省略されます):

cd / path / to / moodle /
$ git config --file = .gitmodulesサブモジュール "mod / mylittleextension" .url "<source:fork>"

またはファイル.gitmodulesをそれぞれ編集します。

その後に入力してください:

$ gitサブモジュール同期
'mod / mylittleextension'のサブモジュールURLの同期
$ git commit -a -m "MLEのソースURLを変更しました"
$ cd mod / mylittleextension
mod / mylittleextension $ gitリモートリネームオリジンフォーク

syncコマンドは、あなたの.gitモジュールの設定に合うようにあなたのサブモジュールのリポジトリのリモートを変更します。サブモジュールのリモート名の変更名前の変更追加など )はMoodleリポジトリでは気付かれません。実際、ファイルを編集したりサブモジュールのHEAD参照を変更したりしない限り、あなたはあなたのブランチを使って何でもすることができます。

やっと開発者も自分のプロジェクトを更新する必要があります。開発者のマシンでは、次のように入力します(出力メッセージは再度省略されます)。

$ cd / path / to / local / repository
$ git pull
$ gitサブモジュールの更新
$ gitサブモジュール同期
$ cd mod / mylittleextension
mod / mylittleextension $ gitリモートリネームオリジンフォーク
mod / mylittleextension $ gitリモートでオリジンを追加<source:origin>
mod / mylittleextension $ gitフェッチ元

繰り返しになりますが、 syncコマンドはサブモジュールのリモート設定を変更してそれらを.gitモジュールと一致させます。

スーパープロジェクトへの貢献

このセクションはあなたのスーパープロジェクトにパッチを提供する方法を説明します。開発者が拡張機能を変更したとし、その変更をサブモジュールのリポジトリにコミットします。

$ cd / path / to / local / repository
$ cd mod / mylittleextension
mod / mylittleextension $ gitブランチ-avv
* dev 9701a0c [fork / dev:ahead 1] 3回目のコミット
  master 5e0e66a [フォーク/マスター] 2回目のコミット
  リモート/フォーク/ HEAD  - >フォーク/マスター
  remotes / fork / dev 5e0e66aセカンドコミット
  リモート/フォーク/マスター5e0e66aセカンドコミット

変更をフォークにプッシュします。

mod / mylittleextension $ gitプッシュフォークdev:master

フォークしたリポジトリを別の方法で編成することもできます。たとえば、開発者が別々のブランチにプッシュして満足できる場合にのみマージするようにします。今のところ、開発者はあなたのマスター (あるいは一般的にはあなたのスーパープロジェクトによって追跡されるブランチ)にプッシュできると仮定します。あなたの開発者のMoodleリポジトリは彼らのコミットからの変更に気づくでしょう:

$ cd / path / to / moodle
$ gitステータス
#ブランチマスター
#変更がコミット用にステージングされていません。
#(コミットされる内容を更新するには "git add <file> ..."を使用してください)
#(作業ディレクトリの変更を破棄するには "git checkout  -  <file> ..."を使用してください)
#
#変更:mod / mylittleextension(新しいコミット)
#
コミットに変更を加えない( "git add"や "git commit -a"を使う)

変更をコミットしないでください。あなたのメインリポジトリのすべての変更はあなたのスーパープロジェクトからのコミットを通して行われると私たちは仮定します。ステータスはただあなたのサブモジュールがあなたのスーパープロジェクトとは別の状態にあることを言っています。しかし、これはまったく問題ではありません。これは後で修正します。 注:サブモジュールに関連しない変更をコミットする必要がある場合、開発者はスーパープロジェクトが更新されるまでサブモジュールをステージングしないようにする必要があります。

スーパープロジェクトのマシンで次のコマンドを使用してスーパープロジェクトを更新します。

(スーパープロジェクトのマシン上)
$ cd / path / to / moodle
$ gitサブモジュールforeach git pull
$ git commit -a -m "プラグインの更新"

あなたの開発者は更新されたスーパープロジェクトを取得することができます。

(開発者のマシン上)
$ cd / path / to / local / repository
$ git pull
$ gitステータス
#ブランチマスター
コミットするもの(作業ディレクトリをクリーン)

ご覧のとおり、開発者はサブモジュールの変更されたステータスをコミットする必要はありません。あなたの開発者のリポジトリは取得後に再びきれいになります。

図:サブモジュールの更新のワークフロー

5番目のコマンド( gitサブモジュールの更新[--init] )は、他のサブモジュールが追加または更新されたときにのみ必要です。

関連情報

Moodleドキュメント
外部リソース