pockestrap

Web Programmer's memo

db/schema.rb のコンフリクトを勝手に解決する git merge driver を作った

解決したい課題

Ruby on Rails を使って開発している方の中で、db/schema.rbがコンフリクトした経験がある方は多いのではないでしょうか?
特にスキーマのバージョンはよくコンフリクトします。

diff --cc db/schema.rb
index bdb07db,da150fc..0000000
--- a/db/schema.rb
+++ b/db/schema.rb
@@@ -10,7 -10,7 +10,11 @@@
  #
  # It's strongly recommended that you check this file into your version control system.
  
++<<<<<<< HEAD
 +ActiveRecord::Schema.define(version: 20170701103541) do
++=======
+ ActiveRecord::Schema.define(version: 20170701103437) do
++>>>>>>> change1
  
    create_table "articles", force: :cascade do |t|
      t.string   "title"

このコンフリクトはバージョンが大きい方を採用することで単純に解決できます。 ですが怠惰が美徳であるプログラマは、このような単純作業を好まないのではないでしょうか?

どうやって解決するのか

github.com

merge_db_schema を使用することにより、この問題を解決できます。 このGemをインストールすると、先程のコンフリクトは自動的に解決されます。

out

なお、このGemはスキーマのversion以外のコンフリクトには何もしません。 そのため、そのようなコンフリクトは人間が解決する必要があります。

インストー

通常のGemと同じく、gem installをします。

$ gem install merge_db_schema

また、Gemfileに以下を追記してbundle installをすることでもインストールが可能です。

# Gemfile
gem 'merge_db_schema'
$ bundle install

そして、merge_db_schema-initコマンドを実行する必要があります。

$ merge_db_schema-init
Initializing .gitattributes ... done!
Add the following code into .git/config, initializing is completed!

[merge "merge_db_schema"]
    name = Merge db/schema.rb
    driver = merge_db_schema %O %A %B
    recursive = text

このコマンドを実行すると上記のように.git/configに追記をするようメッセージが出るので、追記をして下さい。 なおコマンドの実行にbundle execが必要な場合、.git/configdriverにもbundle execを付与する必要があります。

これは何なのか

merge_db_schemaは、git の merge driver です。 merge driverを指定することで、git mergeをする時の挙動をファイル毎に変更することが可能です。

詳しくはドキュメントをご覧ください。

https://git-scm.com/docs/gitattributes