DBFluteでgitコンフリクト (Conflict)
概要
DBFluteでgitコンフリクトが起きた場合、起きないようにする方法など。
DBFluteのファイルは大きく四つ
- 自動生成ファイル (by DBFlute)
- BehaviorやEntity, SchemaHTMLなど
- 元ファイル (by 人間)
- dfpropファイルやDDLやTSVなど
- 蓄積ファイル (by DBFlute)
- 履歴のdiffmap, decomment-pickup, (SchemaXML)
- 一時ファイル (by DBFlute)
- playsqlのdfmarkなど
DB変更から自動生成までの関連ファイル
e.g. DB変更から自動生成までの関連ファイル @Java
o +---------------------+
/|\ -------------------> | ERD tool (ERFlute) | --(save)--> .erm file
/\ +---------------------+
| |
| +--(export)-----------------+
| |
| +--- DBFlute Client -----------------------------/T\-------+
| | |
| | +---- dfprop ------------------------------/T\---+
| | | |
+-(mod)---/T\--> | additioinalForeignKey.dfprop |
| | | basicInfoMap.dfprop |
| | | ... |
| | +------------------------------------------/T\
| | |
| | |
| | +---- playsql -----------------------------/T\----+
| | | |
| | | NextDDL <--(export)-----------+
| | |
| | | <--(ref)---+
+-(mod)---/T\---------------> TSV (test data) |
| | | |
| | | ReplaceSchema
| | |
+-(mod)---/T\---------------> AlterDDL <--(ref)---+
| | | |
| | | AlterCheck
| | |
| | +-------------------------------------------------+
(Replace |
Schema) |
| |
| | +---- schema -------------------------------------+
| | |
(JDBC)------/T\--> | SchemaXML (project-schema-...xml)
| | | SchemaDiffmap (schemadiff/diffpiece-...diffmap)
| | | CraftDiffMeta (previous|next.tsv)
| | |
| +--/T\---/T\--> DecommentPickup (decomment-pickup.dfmap)
| | | | ^
| | | | | (make from pieces)
| | | | +- Doc
| | | |
| | | +-------------------------------------------------+
| | |
| | |
| | | +---- output/doc ---------------------------------+
| | | |
(Doc)----+--/T\--> | SchemaHTML (schema-...html)
| | | HistoryHTML (history-...html)
| | | PropertiesHTML (properties-...html)
| | | ^
| | | | (make)
| | | +- Doc
| | |
| | +-------------------------------------------------+
| |
| +----------------------------------------------------------+
|
| +---- src/main/java or resources --------------------+
| |
| | +-- base world ------------------------------+
(Generate)---> | | allcommon
| | | bsbhv
(Sql2Entity)-> | | bsentity
| | | cbean.bs
| | | cbean.cq.bs
| | | cbean.cq.ciq
| | | cbean.cq.nss
| | +--------------------------------------------+
| |
| | +-- extended world --------------------------+
| | | cbean
+--(mod)----/T\-> | cbean.cq
| | | exbhv
| | | exentity
| | +--------------------------------------------+
| |
| | +-- resouces --------------------------------+
| | | Di xml (if Lasta)
| | +--------------------------------------------+
| |
| | ^
| | | (make)
| | +- Generate
| | Sql2Entity
| |
| +----------------------------------------------------+
コンフリクトが発生した場合
ひとまず今コンフリクトが発生してしまった場合のアプローチを紹介します。
自動生成されたファイルは自動生成し直し
自動生成されたファイルは丁寧にマージする必要はありません。
- dbfluteパッケージのbase系クラスたち (allcommon, bsbhvなど)
- output/docのHTMLファイルたち (SchemaHTMLなど)
自動生成の元になっているファイルたち (dfpropなど) がコンフリクトしていたら、それらを先にマージして自動生成し直せばOKです。
- 元ファイル、蓄積ファイルのコンフリクトを丁寧にマージ
- もういちど自動生成を実行して上書き
dfpropファイルは丁寧にマージ
その元ファイルの代表です。dfpropファイルは人が修正していますから、他人の修正と自分の修正をマージしましょう。
その他、loadingControlMap.dataprop などの ReplaceSchema で使っている datapropファイルも同様です。 (これらも人が手で修正する設定ファイルです)
ERDツールのファイルは丁寧にマージ
もし、ERFluteなどのERDツールを使ってDDLを出力している場合は、そのERDのファイルをマージしましょう。 (ERFluteなら、ermファイルはあまりコンフリクトは発生しませんが、とはいえ可能性はゼロではないです)
ERDツールから出力されたDDLは、自動生成ファイルと言えるので、これらがコンフリクトしても、ERDを正しくマージしていれば、DDL出力し直せば良いだけです。
playsql配下のファイル (DDLやTSVなど) は丁寧にマージ
もし、ReplaceSchemaを利用している場合、playsqlも元ファイルと言えます。これらファイルからスキーマが作成されて自動生成につながります。
DDLがERDツールなどから自動生成されている場合は、元ファイル扱いではなく自動生成ファイル扱いになるので、ERDファイル自体をマージして出力し直しましょう。
一方で、tsv-data-result.dfmarkなどのReplaceSchemaのデータ登録処理の出力結果などは、一時的な出力情報ということなので、ReplaceSchemaし直して上書きすればOKです。 (そもそも tsv-data-result.dfmark は gitignore して良いでしょう)
schema配下のSchemaXMLはDB直してJDBCタスクし直し
SchemaXMLは、MySQL自体のスキーマから導出されるものなので、スキーマの元になっているDDLのコンフリクトを修正して、MySQLに反映させてからJDBCタスクをし直せば、マージされたSchemaXMLができあがります。
ReplaceSchemaを利用している場合は、ReplaceSchemaの元になっているDDLやデータTSVファイルのコンフリクトをマージしてから ReplaceSchema を実行して、そして、JDBCタスクを実行しましょう。
ただ、他のコンフリクトが解消してから実施しましょう。 (他のコンフリクトが残ってると、そもそもReplaceSchemaもJDBCも落ちたり変な結果を出したりするかもしれませんので)
schema配下の SchemaDiffmap は...バージョン次第
DBFluteが集めたスキーマ差分の蓄積データですが、DBFluteのバージョンに寄ります。
DBFlute-1.2.6 以降であれば、そもそもコンフリクトしません。スキーマ差分のファイル (SchemaDiffmap) は個別に独立しているためです。(ミリ秒単位のファイル名になっている)
DBFlute-1.2.5 までであれば、スキーマ差分が一つにまとまっている (HistoryDiffmap) ので、このファイルは丁寧にマージする必要があります。
schema配下のCraftDiffMeta (tsv) は丁寧にマージ
DBFluteが集めたDBデータの差分の蓄積データです。丁寧にマージしましょう。
schema配下decommentのpickupファイルは丁寧にマージ
DBFluteが集めたdecommentの蓄積データです。丁寧にマージしましょう。
ただ、pickupDatetimeの日時がコンフリクトしてるだけのケースが多いでしょう。日時は最新の方を優先でOKです。
コンフリクトしないためには?
A. 自動生成タスクは代わりばんこに
例えば、alter_dbブランチというDB変更や自動生成を実施する専用のブランチを作成して、複数の人が同時に自動生成を実行しないようにします。
ただ、人間的な運用が必要です。そのブランチの修正者が同時に必ず一人になるようにチーム内でうまく情報共有しましょう。
(これが一番多いパターンです)
長いスパンの別ブランチ開発があってどうしても並列でDB変更と自動生成を行う場合は、本線とマージするときにコンフリクトが発生し自動生成し直しと丁寧マージが必要にはなるでしょう。 (そこは時々なので許容してマージ頑張るということになるでしょう)
B. 自動生成クラスのBsクラスをgitignoreに
自動生成されるクラスやファイルをgitignoreにすることで、自動生成ファイルのコンフリクトは発生しません。 ただ、各開発者にはブランチを切り替えるたびにつどつど自動生成 (renewal or regenerate) をしてもらう必要があります。
- allcommonパッケージ
- bsbhvパッケージ
- bsentityパッケージ
- cbean.bsパッケージ
- cbean.cq.bsパッケージ
- cbean.cq.ciqパッケージ
- cbean.nssパッケージ
- DIコンテナ用の設定ファイル (e.g. dbflute.xml)
- SchemaHTML: DBFluteクライアント/output/doc/schema-*.html
- HistoryHTML: DBFluteクライアント/output/doc/history-*.html
- PropertiesHTML: DBFluteクライアント/output/doc/properties-*.html
- LastaDoc: DBFluteクライアント/output/doc/lasta-*.html (Lastaのみ)
- playsql/data配下のdfmark: (e.g. xls-data-result.dfmark, tsv-data-result.dfmark)
e.g. src/main/javaのdbfluteパッケージ配下の.gitignore @Java
# DBFlute GenIgnored
## Base packages
/allcommon
/bsbhv
/bsentity
/cbean/bs
/cbean/cq/bs
/cbean/cq/ciq
/cbean/nss
e.g. src/main/resources配下の.gitignore (LastaFluteの場合のみ) @Java
# DBFlute GenIgnored
## Di xml for LastaFlute
/dbflute*.xml
e.g. DBFluteクライアントのoutput/doc配下の.gitignore @Java
# DBFlute GenIgnored
## output documents
/schema-*.html
/history-*.html
/properties-*.html
/lastadoc-*.html
ただし、HistoryHTMLの履歴データである schema/project-history-*.diffmap は、ignoreにしてはいけません。 これはDDLだけでは再現できない情報なので蓄積させる必要があります。また、decommentやhacommentのpieceファイルやpickupファイルも同様です。 これらは、自動生成ファイルというよりは、DBFluteが保存しているファイルと言えます。
一方で、自動生成ではないファイルのコンフリクトは変わらず丁寧にマージする必要はあります。
また、SavePreviousのファイルは、自動生成とは別のライフサイクルなので一概にignoreにはできないでしょう。 (クラスの自動生成と SavePrevious は別物と考えたほうが良いです)
C. 自動生成し直しと丁寧マージをしっかり
割り切ってみんなで丁寧にマージしていこうというやり方も可能性としてはあります。
本ページのコンフリクトが発生した場合を参考に、各々が自動生成し直しマージを実施します。
中途半端なignoreは非推奨
例えば、SchemaHTMLだけignore、HistoryHTMLだけignore、というような中途半端なignoreはオススメしていません。強く非推奨です。
各開発者がローカルで自動生成を行う義務がなければ、結局それらファイルはローカルに存在しないことになり、それら機能が活用されなくなってしまうからです。
DBFluteの機能は地味なものだらけで、その機能のためにわざわざ狙って何か実行するってことにはなりにくいのですが、目の前にあれば便利だなって感じるような機能が多いです。 ゆえに、開発者としては、中途半端なignoreは避けてもらいたいという気持ちがあります。 (ignoreにするなら、全ての自動生成ファイルをignoreにするようにした方が良いのかなと)
一方で、decommentサーバー方式を採用していて、SchemaHTMLなどは社内サーバー上の DBFlute Intro経由で閲覧するような仕組みになっていればまた話は別です。
一方で一方で、playsql/data配下のdfmarkなどは元々一時的な出力のものなので、これらはピンポイントでignoreしても良いでしょう。
