schema.rb
を.gitignore
に追加したくないのは、そのファイルから新しいデータベーススキーマをロードできるようにするためです。ただし、チェックインしたままにしておくと、新しいdb:migrate:reset
で簡単に解決できるあらゆる種類の偽の競合が発生します。
基本的に私は次の方法が必要です:
schema.rb
を更新し、それが正しいことを知っている責任者は1人か2人です。
ケーキを持って食べる方法はありますか?
私にとって本当にうまくいったのは、schema.rb
を削除して.gitignoreし、開発者がrake db:migrate
したときに開発者ごとに再生成することです。
定期的に移行の「ロールアップ」を行うだけで、0から移行したり、数年前から移行が失敗したりするリスクを冒すことなく、目的を達成できます。これは次の方法で実行できます。
rake db:migrate
を使用してすべての未処理の移行を実行しますschema.rb
ブロックのActiveRecord::Schema.define
の内容を取得するdef up
内のinitial_schema移行に貼り付けます(すでに存在するものを上書きします)これで、initial_schemaの移行が新しいシステムの開始点になり、正しく解決されない可能性のあるschema.rb
の競合について心配する必要がなくなりました。それは魔法ではありませんが、機能します。
あなたが探している魔法の解決策は存在しないのではないかと思います。このファイルは通常、バージョン管理で管理されます。バージョン行で競合が発生した場合は、2つの日付のうち遅い方を選択してください。関連するすべての移行も実行している限り、この方法で同期が外れることはありません。 2人の開発者がschema.rbの同様の領域に変更を加え、バージョンに加えて競合が発生した場合、通常のマージ競合の解決に直面しますが、私の意見では、これらは通常、理解と解決が容易です。これがお役に立てば幸いです。
あなたができるもう一つのことは使用することです:
git update-index --assume-unchanged /path/schema.rb
これにより、ファイルはリポジトリに保持されますが、変更は追跡されません。次を使用して、いつでも追跡を切り替えることができます。
git update-index --no-assume-unchanged /path/schema.rb
.gitignore
を使用する代わりに、別々のブランチを使用します:schema.rb
とDevelop
を省略したTest
とschema.rb
を含むDeploy
。開発ブランチでのみコードを変更し、Test
からDevelop
にマージしないでください。 schema.rb
を別のブランチに保持します。
Developer A
Develop --------
Local Schema \ Your Repo
Test ---------> Dev A
---------> Dev B
Developer B / Master
Develop -------- Schema
Local Schema Test
Test Deploy
Gitでは、ブランチはファイルコンテンツのコレクションへのポインターであるため、特定のファイルを含めたり除外したり、ファイルバージョンを追跡したりできます。これにより、特定のワークフローを構築するための柔軟なツールになります。
マージ戦略を定義できます。私はこの解決策を見つけましたが、ソースを覚えていません
[merge "railsschema"]
name = newer Rails schema version
driver = "Ruby -e '\n\
system %(git), %(merge-file), %(--marker-size=%L), %(%A), %(%O), %(%B)\n\
b = File.read(%(%A))\n\
b.sub!(/^<+ .*\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n=+\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n>+ .*/) do\n\
%(ActiveRecord::Schema.define(:version => #{[$1, $2].max}) do)\n\
end\n\
File.open(%(%A), %(w)) {|f| f.write(b)}\n\
exit 1 if b.include?(%(<)*%L)'"
これを「どこかに」置いて
git-config --global core.attributesfile "somewhere"
私はこの問題を解決するために宝石を作りました。
列、インデックス名、外部キーを並べ替え、余分な空白を削除し、Rubocopを実行してフォーマットを行い、schema.rbファイルの出力を統合します。
https://github.com/jakeonrails/fix-db-schema-conflicts
それをGemfileに追加した後、通常のようにrake db:migrate
またはrake db:schema:dump
を実行するだけです。
コミット前のgitフックでrakedb:dumpを実行するだけで十分でしょうか?
以下は、必ずしも(1)または(2)を修正するわけではありませんが、マージの問題を処理する可能性があり、その後、(1)および(2)がなくなる可能性があります。
schema.rb
ファイルをコミットします。データベースを移行するたびに、schema.rb
ファイルが更新され、git status
に表示されます。何かに取り組んでいて、時々git pull
を実行する場合、競合を解決するためにプルする前にschema.rb
ファイルをコミットする必要があるため、これは煩わしい場合があります。これは、データベースを移行するたびに、schema.rb
ファイルをコミットする必要があることを意味します。