Reduce Your Rails Schema Conflicts
24 Oct 2010
Update: hookup does all this for you and more!
Tired of conflicts on your schema file that boil down to the version specification at the top? Me too. After reading Will Leinweber’s article on resolving Gemfile.lock conflicts automatically, I decided I could do better. I started with a tweet and a gist, but after seeing the reception it received, I’m expanding it to a full-on blog post.
The snippet below goes in your ~/.gitconfig
, and is basically a simple
algorithm that resolves a schema version conflict by picking the higher
number. Personally, I’d rather have an ugly mess in my Git config file
than a second file I have to copy around everywhere or a gem I have to
install.
[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)'"
Now all that’s left is to tell Git to use that algorithm for
db/schema.rb
. You have to do this on a per project basis. You can
either commit it to .gitattributes
or keep it locally in
.git/info/attributes
.
db/schema.rb merge=railsschema
That’s it. I haven’t beat on it too hard yet, but it’s handled simple conflicts beautifully.