在 git 中管理 schema.rb 的首选方法是什么?
我不想将 schema.rb
添加到 .gitignore
,因为我希望能够从该文件加载新的数据库架构。 然而,保持其签入状态会导致各种虚假冲突,这些冲突可以通过新的 db:migrate:reset 轻松解决。
基本上我想要一种方法:
- 将 schema.rb 保留在存储库中以进行部署时数据库设置
- 将 schema.rb 保留在“.gitignore”中以进行一般开发
将有一两个人负责更新 schema.rb 并知道它是正确的。
有没有办法既能鱼与熊掌兼得呢?
I don't want to add schema.rb
to .gitignore
, because I want to be able to load a new database schema from that file. However, keeping it checked in is causing all sorts of spurious conflicts that are easily resolved by a fresh db:migrate:reset
.
Basically I want a way to:
- Keep schema.rb in the repository for deploy-time database setup
- Keep schema.rb in '.gitignore' for general development
There would be one or two people responsible for updating schema.rb
and knowing that it was correct.
Is there a way I can have my cake and eat it, too?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
恐怕您正在寻找的神奇解决方案并不存在。 该文件通常在版本控制中管理,然后对于版本行上的任何冲突,只需选择两个日期中较晚的一个。 只要您还运行所有关联的迁移,就不应该以这种方式失去同步。 如果两个开发人员对 schema.rb 的类似区域进行了修改,并且除了版本之外还出现了冲突,那么您将面临正常的合并冲突解决方案,但在我看来,这些通常很容易理解和解决。 我希望这对一些人有帮助!
I'm afraid the magic solution you're looking for does not exist. This file is normally managed in version control, then for any conflicts on the version line just choose the later of the two dates. As long as you're also running all of the associated migrations nothing should get out of sync this way. If two developers have caused modifications to a similar area of schema.rb and you get conflicts in addition to the version then you are faced with a normal merge conflict resolution, but in my opinion these are normally easy to understand and resolve. I hope this helps some!
您可以做的另一件事是使用:
这会将文件保留在存储库中,但不会跟踪更改。 您可以随时使用以下方式切换跟踪:
One other thing you can do is use:
This will keep the file in the repository but won't track changes. you can switch the tracking anytime by using:
对我来说非常有效的方法是删除 .gitignore
schema.rb
,然后在每个开发人员rake db:migrate
时重新生成它。您仍然可以实现您想要的目标,而无需从 0 开始迁移,也无需冒着几年前迁移失败的风险,只需定期“汇总”迁移即可。 您可以通过以下方式执行此操作:
rake db:migrate
运行所有未完成的迁移ActiveRecord::Schema.defineschema.rb
的内容code> blockdef up
内的initial_schema迁移中(覆盖已有的内容)现在,您的initial_schema迁移是新系统的起点,您不必担心冲突在
schema.rb
中,可能无法正确解析。 这并不神奇,但确实有效。What has worked really well for me is to delete and .gitignore
schema.rb
and then have it regenerated for each developer when theyrake db:migrate
.You can still achieve what you wanted without migrating from 0 and risking broken migrations from years ago by simply doing a "roll-up" of the migrations periodically. You can do this by:
rake db:migrate
schema.rb
in theActiveRecord::Schema.define
blockdef up
(overwriting what's already there)Now your initial_schema migration is your starting point for new systems and you don't have to worry about conflicts in
schema.rb
that may not be resolved correctly. It's not magical, but it works.在预提交 git hook 中执行 rake db:dump 就足够了吗?
以下内容不一定会解决(1)或(2),但它可能会解决合并问题,然后(1)和(2)可能会消失。
Would it be sufficient to do a rake db:dump in a pre-commit git hook?
The following won't necessarily fix (1) or (2), but it might take care of the merging issue, and then maybe (1) and (2) go away.
不要使用
.gitignore
,而是使用单独的分支:Develop
,其中省略schema.rb
和Test
和部署
,其中包含schema.rb
。 仅在开发分支中进行代码更改,切勿从Test
合并到Develop
。 将 schema.rb 保留在单独的分支中:在 Git 中,分支是指向文件内容集合的指针,因此它们可以包含或排除特定文件以及跟踪文件版本。 这使得它们成为构建特定工作流程的灵活工具。
Instead of using
.gitignore
, use separate branches:Develop
which omitsschema.rb
andTest
andDeploy
which includeschema.rb
. Only make code changes in the Develop branches and never merge fromTest
intoDevelop
. Keepschema.rb
in a separate branch:In Git, branches are pointers to collections of file contents, so they can include or exclude particular files as well as track file versions. This makes them flexible tools for building your particular workflow.
您可以定义合并策略。
我找到了这个解决方案,但不记得来源
将此放在“某处”并且
You could define a merge strategy.
I've found this solution, but dont remember the source
put this "somewhere" and
我构建了一个 gem 来解决这个问题。
它对列、索引名称和外键进行排序,删除多余的空格并运行 Rubocop 进行某些格式化以统一 schema.rb 文件的输出。
https://github.com/jakeonrails/fix-db-schema-conflicts
将其添加到 Gemfile 后,您只需像平常一样运行
rake db:migrate
或rake db:schema:dump
即可。I built a gem to solve this problem.
It sorts columns, index names and foreign keys, removes excess whitespace and runs Rubocop for some formatting to unify the output of your schema.rb file.
https://github.com/jakeonrails/fix-db-schema-conflicts
After you add it to your Gemfile you just run
rake db:migrate
orrake db:schema:dump
like normal.每次迁移数据库时,
schema.rb
文件都会更新并显示在git status
中。 当处理某些事情并偶尔执行 git pull 时,这可能会很烦人,因为您必须在拉取之前提交 schema.rb 文件才能解决冲突。 这意味着每次迁移数据库时,都需要提交 schema.rb 文件。schema.rb
file.Every time you migrate the database, the
schema.rb
file updates and appears ingit status
. When working on something and occasionally doinggit pull
, this can be annoying because you have to commitschema.rb
file before pulling to resolve conflict. This means that every time you migrate the database, you need to commitschema.rb
file.当然,
schema.rb
应该被 Git 跟踪。我刚刚发布了这个 gem,它可以永久解决分支之间的“冲突”问题。
该宝石的想法很简单。 它将所有已迁移的迁移保留在
tmp
文件夹中,以便 Git 忽略它们。 这只是你当地的故事。 需要这些文件来回滚另一个分支中的“未知”迁移。 现在,每当由于在其他分支中运行迁移而导致数据库架构不一致时,只需在当前分支内运行rails db:migrate
,它就会自动修复问题。 宝石会自动为您完成所有这些魔法。schema.rb
should be tracked Git, of course.I've just released this gem that can solve an issue with "conflicts" between branches for good.
The idea of that gem is simple. It keeps all migrated migrations inside
tmp
folder so that Git ignores them. It's just only your local story. These files are needed to roll back the "unknown" migrations being in another branch. Now, whenever you have an inconsistent DB schema due to running migrations in some other branch just runrails db:migrate
inside the current branch and it will fix the issue automatically. The gem does all this magic automatically for you.