在git中管理schema.rb的首选方法是什么?

时间:2009-04-10 14:48:08

标签: ruby-on-rails git workflow schema.rb

我不想将schema.rb添加到.gitignore,因为我希望能够从该文件加载新的数据库架构。但是,保持登记状态会导致各种虚假冲突,这些冲突很容易被新的db:migrate:reset解决。

基本上我想要一种方法:

  1. 将schema.rb保留在存储库中以进行部署时数据库设置
  2. 将schema.rb保留在'.gitignore'中以进行常规开发
  3. 将有一两个人负责更新schema.rb并知道它是正确的。

    有没有办法可以吃蛋糕并吃掉它?

8 个答案:

答案 0 :(得分:21)

我担心你所寻找的神奇解决方案不存在。此文件通常在版本控制中进行管理,然后对于版本行上的任何冲突,只需选择两个日期中的较晚者。只要您还运行所有相关的迁移,任何事情都不会以这种方式失去同步。如果两个开发人员对schema.rb的类似区域进行了修改,并且除了版本之外还会遇到冲突,那么您将面临正常的合并冲突解决方案,但在我看来,这些通常很容易理解和解决。我希望这会有所帮助!

答案 1 :(得分:8)

您可以做的另一件事是:

git update-index --assume-unchanged /path/schema.rb

这会将文件保留在存储库中,但不会跟踪更改。您可以随时使用以下方式切换跟踪:

git update-index --no-assume-unchanged /path/schema.rb

答案 2 :(得分:2)

对我来说非常有效的方法是删除和.gitignore schema.rb,然后在每个开发人员rake db:migrate时为其重新生成。

通过简单地定期“迁移”迁移,您仍然可以实现您想要的,而无需从0迁移,并且可能会在几年前破坏迁移的风险。您可以通过以下方式执行此操作:

  1. 使用rake db:migrate
  2. 运行所有未完成的迁移
  3. schema.rb区块
  4. 中获取ActiveRecord::Schema.define的内容
  5. 将其粘贴到def up内的initial_schema迁移中(覆盖已存在的内容)
  6. 删除所有其他迁移
  7. 现在,您的initial_schema迁移是新系统的起点,您不必担心schema.rb中可能无法正确解决的冲突。这不是神奇的,但它确实有效。

答案 3 :(得分:1)

在pre-commit git hook中执行rake db:dump是否足够?

以下不一定会修复(1)或(2),但它可能会解决合并问题,然后可能(1)和(2)消失。

答案 4 :(得分:1)

不使用.gitignore,而是使用单独的分支:Develop,其中省略了schema.rbTest以及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

在Git中,分支是指向文件内容集合的指针,因此它们可以包含或排除特定文件以及跟踪文件版本。这使它们成为构建特定工作流程的灵活工具。

答案 5 :(得分:1)

您可以定义合并策略。 我找到了这个解决方案,但不记得来源

[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"

答案 6 :(得分:1)

我建造了一个宝石来解决这个问题。

它对列,索引名和外键进行排序,删除多余的空格并运行Rubocop以进行某些格式化以统一schema.rb文件的输出。

https://github.com/jakeonrails/fix-db-schema-conflicts

将其添加到Gemfile后,您就像正常一样运行rake db:migraterake db:schema:dump

答案 7 :(得分:0)

  1. 提交schema.rb文件。
  2. 运行git pull(或继续你正在做的事情)
  3. 每次迁移数据库时,schema.rb文件都会更新并显示在git status中。在处理某些事情并偶尔执行git pull时,这可能很烦人,因为在解决冲突之前必须提交schema.rb文件。这意味着每次迁移数据库时,都需要提交schema.rb文件。