As a Rails developer, you'll be faced with plenty
schema.rb conflicts when attempting to rebase on your base branch. A quick bit of research tells us simply
rake db:migrateing regenerates a merged
schema.rb file. That's fine if your database is free of schema changes from other branches. When working on multiple branches, each with migrations that you've run on your development database, this approach undesirably includes those unrelated changes.
Firstly, I highly recommend using your test database to work through correcting
schema.rb because it's super fast (no data in it) and you won't wipe out your development data when rebuilding your schema. That is to say, your development DB can have any conglomeration of migrations (that you may or may not even keep) while your test DB remains pristine or close to it. Add
RAILS_ENV=test to your rake commands below.
The solution depends on one particular best practice -- write your damn
down methods! I can point to maybe two or three exceptions in my experience because of complexity or difficulty of reproducing the original data.
With that out of the way, a note about what does not work. You may be inclined to rebuild the database via
rake db:setup with a clean
schema.rb from your master branch. Problem is,
rake db:setup does not have any way of knowing that your topic branch migration version ID should be removed from the
schema.rb only knows the newest version ID. It could remove all version IDs from
schema_migrations that are older than this ID, but I think it almost always would be newer than your topic branch migration ID if you are having conflicts, because the other migrations are probably from your colleagues making schema changes after you generated your migration.
rake db:setup approach would recreate your database without the schema change introduced by your topic branch, except with its version number in
schema_migrations. The result is a migration that looks like it has run, but hasn't.
With Migrations In-Sync
If you're not in the situation described above, do the following.
- Roll back your new migration:
rake db:migrate:down VERSION=(stamp).
- Check out an unmodified
schema.rbfile from your branch's base (probably master):
git checkout master -- db/schema.rb.
- Rebuild your database from
- Re-run your new migration:
At this point your
schema.rb should look correct.
With Migrations Out-Of-Sync
If you're really in a mess, another possibility is
rake db:drop && rake db:setup with your base branch checked out, before rebasing at all. That will nuke
schema_migrations and re-populate it with all version IDs found in
db/migrate, which excludes your topic branch migration ID because you're not on your topic branch. Then, you can switch to it, rebase, and
rake db:migrate normally.
Another way of thinking about it is that you need to re-apply your schema changes in the same way that you'd re-apply your code changes when running into merge conflicts. You're taking the new database blueprint and re-running your change to it. Starting with that new blueprint, however, can be a little squirrely.