在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 03:38:31  来源:igfitidea点击:

What is the preferred way to manage schema.rb in git?

ruby-on-railsgitworkflowschema.rb

提问by Otto

I don't want to add schema.rbto .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:

基本上我想要一种方法:

  1. Keep schema.rb in the repository for deploy-time database setup
  2. Keep schema.rb in '.gitignore' for general development
  1. 将 schema.rb 保留在存储库中以进行部署时数据库设置
  2. 将 schema.rb 保留在“.gitignore”中以进行一般开发

There would be one or two people responsible for updating schema.rband 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.rband 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 迁移,也无需冒几年前迁移中断的风险,只需定期对迁移进行“汇总”即可。您可以通过以下方式执行此操作:

  1. Run all outstanding migrations with rake db:migrate
  2. Taking the contents of your schema.rbin the ActiveRecord::Schema.defineblock
  3. Paste it into your initial_schema migration inside def up(overwriting what's already there)
  4. Delete all other migrations
  1. 运行所有未完成的迁移 rake db:migrate
  2. 将您的内容schema.rb放入ActiveRecord::Schema.define块中
  3. 将它粘贴到你的 initial_schema 迁移里面def up(覆盖已经存在的内容)
  4. 删除所有其他迁移

Now your initial_schema migration is your starting point for new systems and you don't have to worry about conflicts in schema.rbthat 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:migrateor rake db:schema:dumplike normal.

将它添加到 Gemfile 后,您只需运行rake db:migraterake db:schema:dump像往常一样。

回答by Paul

Instead of using .gitignore, use separate branches: Developwhich omits schema.rband Testand Deploywhich include schema.rb. Only make code changes in the Develop branches and never merge from Testinto Develop. Keep schema.rbin a separate branch:

而不是使用的.gitignore,使用单独的分支:Develop其省略schema.rb,并TestDeploy包括schema.rb。仅在 Develop 分支中进行代码更改,切勿从 合并TestDevelop. 保持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

  1. Commit schema.rbfile.
  2. Run git pull (or continue with what you're doing)
  1. 提交schema.rb文件。
  2. 运行 git pull (或继续你正在做的事情)

Every time you migrate the database, the schema.rbfile 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.rbfile before pulling to resolve conflict. This means that every time you migrate the database, you need to commit schema.rbfile.

每次迁移数据库时,schema.rb文件都会更新并以git status. 在处理某些事情并偶尔做 时git pull,这可能很烦人,因为您必须schema.rb在拉动解决冲突之前提交文件。这意味着每次迁移数据库时,都需要提交schema.rb文件。