在 git 中管理 schema.rb 的首选方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/737854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the preferred way to manage schema.rb in git?
提问by Otto
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
.
我不想添加schema.rb
到.gitignore
,因为我希望能够从该文件加载新的数据库模式。但是,保持检查状态会导致各种虚假冲突,这些冲突很容易被新的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
- 将 schema.rb 保留在存储库中以进行部署时数据库设置
- 将 schema.rb 保留在“.gitignore”中以进行一般开发
There would be one or two people responsible for updating schema.rb
and knowing that it was correct.
会有一两个人负责更新schema.rb
并知道它是正确的。
Is there a way I can have my cake and eat it, too?
有没有办法让我也吃蛋糕?
采纳答案by Tom Harris
What has worked really well for me is to delete and .gitignore schema.rb
and then have it regenerated for each developer when they rake db:migrate
.
对我来说真正有效的是删除和 .gitignoreschema.rb
然后让每个开发人员在他们.gitignore时重新生成它rake 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:
您仍然可以实现您想要的目标,而无需从 0 迁移,也无需冒几年前迁移中断的风险,只需定期对迁移进行“汇总”即可。您可以通过以下方式执行此操作:
- Run all outstanding migrations with
rake db:migrate
- Taking the contents of your
schema.rb
in theActiveRecord::Schema.define
block - Paste it into your initial_schema migration inside
def up
(overwriting what's already there) - Delete all other migrations
- 运行所有未完成的迁移
rake db:migrate
- 将您的内容
schema.rb
放入ActiveRecord::Schema.define
块中 - 将它粘贴到你的 initial_schema 迁移里面
def up
(覆盖已经存在的内容) - 删除所有其他迁移
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.
现在您的 initial_schema 迁移是您新系统的起点,您不必担心schema.rb
可能无法正确解决的冲突。这并不神奇,但它有效。
回答by Adam Alexander
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!
恐怕您正在寻找的神奇解决方案不存在。这个文件通常在版本控制中管理,然后对于版本行上的任何冲突,只需选择两个日期中较晚的一个。只要您还运行所有相关的迁移,就不会以这种方式不同步。如果两个开发人员对 schema.rb 的类似区域进行了修改,并且除了版本之外还遇到了冲突,那么您将面临正常的合并冲突解决方案,但在我看来,这些通常很容易理解和解决。我希望这对一些人有所帮助!
回答by Headshota
One other thing you can do is use:
您可以做的另一件事是使用:
git update-index --assume-unchanged /path/schema.rb
This will keep the file in the repository but won't track changes. you can switch the tracking anytime by using:
这会将文件保留在存储库中,但不会跟踪更改。您可以随时使用以下方法切换跟踪:
git update-index --no-assume-unchanged /path/schema.rb
回答by andrea
You could define a merge strategy. I've found this solution, but dont remember the source
您可以定义合并策略。我找到了这个解决方案,但不记得来源
[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 => #{[, ].max}) do)\n\
end\n\
File.open(%(%A), %(w)) {|f| f.write(b)}\n\
exit 1 if b.include?(%(<)*%L)'"
put this "somewhere" and
把这个“某处”和
git-config --global core.attributesfile "somewhere"
回答by jakeonrails
I built a gem to solve this problem.
我构建了一个 gem 来解决这个问题。
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.
它对列、索引名称和外键进行排序,删除多余的空格并运行 Rubocop 进行某种格式设置以统一您的 schema.rb 文件的输出。
https://github.com/jakeonrails/fix-db-schema-conflicts
https://github.com/jakeonrails/fix-db-schema-conflicts
After you add it to your Gemfile you just run rake db:migrate
or rake db:schema:dump
like normal.
将它添加到 Gemfile 后,您只需运行rake db:migrate
或rake db:schema:dump
像往常一样。
回答by Paul
Instead of using .gitignore
, use separate branches: Develop
which omits schema.rb
and Test
and Deploy
which include schema.rb
. Only make code changes in the Develop branches and never merge from Test
into Develop
. Keep schema.rb
in a separate branch:
而不是使用的.gitignore
,使用单独的分支:Develop
其省略schema.rb
,并Test
与Deploy
包括schema.rb
。仅在 Develop 分支中进行代码更改,切勿从 合并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
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.
在 Git 中,分支是指向文件内容集合的指针,因此它们可以包含或排除特定文件以及跟踪文件版本。这使它们成为构建特定工作流程的灵活工具。
回答by dbrown0708
Would it be sufficient to do a rake db:dump in a pre-commit git hook?
在预提交的 git hook 中执行 rake db:dump 是否足够?
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.
以下不一定会解决(1)或(2),但它可能会解决合并问题,然后(1)和(2)可能会消失。
回答by Chemist
- Commit
schema.rb
file. - Run git pull (or continue with what you're doing)
- 提交
schema.rb
文件。 - 运行 git pull (或继续你正在做的事情)
Every time you migrate the database, the schema.rb
file updates and appears in git status
. When working on something and occasionally doing git pull
, this can be annoying because you have to commit schema.rb
file before pulling to resolve conflict. This means that every time you migrate the database, you need to commit schema.rb
file.
每次迁移数据库时,schema.rb
文件都会更新并以git status
. 在处理某些事情并偶尔做 时git pull
,这可能很烦人,因为您必须schema.rb
在拉动解决冲突之前提交文件。这意味着每次迁移数据库时,都需要提交schema.rb
文件。