Avoiding problems with database changes in feature branches | NetEngine

Avoiding problems with database changes in feature branches

Robert Friday, 18 January 2013

From time to time, while working on a feature branch, a situation arises when you need to make an immediate change on a non-feature branch. You stash your changes, check out the hot fix branch, replicate the bug, add a test to replicate the issue, fix the bug, and as you’re running your tests to confirm your fix hasn’t introduced any regressions, something breaks in a completely unrelated part of your project. There’s nothing like spending 30 minutes figuring out what’s breaking your tests only to find that database changes you’ve made in your feature branch are the problem.

Uncaptioned irxk4 50ba7095c96dd

Recently, after being bitten by this a second time, I went Googling and found a blog post with a workable solution. The solution is to dynamically change the application’s database name by setting Git configuration options for the feature branch.

    $ git config --bool branch.feature.database true

Additionally a few lines of Ruby need to be added to the top of your config/database.yml file.

## database.yml
<%
  branch = `git symbolic-ref HEAD 2>/dev/null`.chomp.sub('refs/heads/', '')
  suffix = `git config --bool branch.#{branch}.database`.chomp == 'true' ? "_#{branch}" : ''
%>
development:
    # ... adapter/auth config ...
    database: myapp<%= suffix %>

While the core of this solution is great, I find that my branch names can get a little wordy, which means the database name ends up being a bit long by extension. As a way to deal with this I’ve modified Mislav’s solution to use a branch alias as the database name suffix. This requires an additional configuration setting and a minor tweak to the above code.

## database.yml
<%
    branch       = `git symbolic-ref HEAD 2>/dev/null`.chomp.sub('refs/heads/', '')
    branch_alias = `git config branch.#{branch}.alias`.chomp
    suffix       = `git config --bool branch.#{branch}.database`.chomp == 'true' ? "_#{(branch_alias.presence || branch)}" : ''
%>

Then all you need to do is add a branch alias and you’re good to go:

    $ git config branch.feature.alias branch-alias

The great thing about the above solution is that it will fallback on the branch name if the alias isn’t present. All that’s left to do is create your branch’s database, populate it with your data, and restart your app.

    $ rake db:create
    $ mysqldump -u root myapp | mysql -u root myapp_feature

Hope this helps out and happy branching!

comments powered by Disqus