Resolving a schema conflict during rebase in Rails
March 12, 2021
After years of (mostly) JavaScript frontend work, I recently joined a large scale project heavily based on Rails. Which means I have now to dive deep into concepts I hadn't touched for a while, including database manipulation.
Ruby on Rails, like many frameworks, relies on migration files to ensure consistency in the way its database builds. These migrations help structure the db in a logical way, providing timestamps, building instructions and other relationships information between tables.
Once the database has been built or updated (rake db:migrate), a file named schema.rb also gets updated detailing its structure. One important details about schema.rb : it should not be manually edited and it relies on a versioning system.
If your team works on many branches, the following situation can easily happen:
- • A migration is created on master branch, schema.rb updates its version
- • You create a migration on your feature branch, schema.rb updates its version
- • Before merging your feature branch, you try to rebase it from master and inevitably face a merge conflict on schema.rb 😱
Trying to manually solve the conflict is not recommended as it will most likely lead to later issues. So how can we solve this?
This blog post gives a great explanation of the situation. Here is my cheatsheet after a few trials & errors, strongly inspired from it:
1) On your feature branch, rollback your conflicting migration (rake db:rollback) or start from a fresh database by dropping it (rake db:drop) and recreating it (rake db:setup). This will clean your database from the tables originating from your feature branch. Be careful, this step also means potential data loss.
2) Start on the master branch and check your migration status: rake db:migrate:status. Everything should be up, meaning all the migrations have been run. If not, run them.
3) Move to your feature branch and rebase: git rebase master. That's where the fun starts.
At the first conflict, unstage & discard the schema file by running
git reset HEAD db/schema.rb
git checkout db/schema.rb
4) Solve your (potential) other conflicts and run git rebase --continue
5) If your feature branch had many previous commit, you might have other conflicts to resolve. Simply repeat steps 3 & 4 for each of them.
6) Once all conflicts have been solved, run rake db:migrate. You should see your feature branch's migration info appear in the console.
7) Check your schema.rb file and make sure it includes your new table. Finally, run rake db:migrate:status and check all migrations are up.
Congratulations, you made it 👏
You can now resume your life and live happily ever after.