Finding Rails migrations
Tags: rails, git
Published: 2018-08-13 17:19:07

---
title: Finding Rails migrations
published: true
description: When you are working on many Git branches in a project, you might need to track Ruby on Rails migrations across these branches. How can you easily do that?
tags: rails, git
canonical_url: https://michaeljherold.com/2018/08/13/finding-rails-migrations/
---

<img src="https://thepracticaldev.s3.amazonaws.com/i/oi1xuee9oiz1x32pozhg.jpg" alt="Scrabble pieces arranged to spell S-E-A-R-C-H signifying the search for Rails migrations across branches." />

Sometimes, I find myself working across several branches helping different teammates with their stories. Often, these branches use Rails migrations to easily manage the database changes that need to be made to support the work. This means that I end up running migrations from many different branches. Because I am human, I often forget to roll those migrations back before switching branches. When a destructive migration has to happen as part of a branch, it leaves me in a situation where I have several migrations that I need to roll back at any given time. In addition, they might be interleaved with migrations that exist on the `master` branch if it's a longer-running branch.

<!--more-->

## Missing Rails migrations

When I have database migrations that I want to track across branches, I use [`rails db:migrate:status`](https://guides.rubyonrails.org/command_line.html#bin-rails) to see what the status is for every migration that exists on my current branch. However, when I have run migrations that haven't been merged into the `master` branch, that leaves me with output that looks like this:

```
   up     20180301163041  Add chocolate chips to the cookies
   up     20180302132931  ********** NO FILE **********
   up     20180302161231  Remove the egg from the recipe
   up     20180306171402  Change flour to almond flour
```

I find myself wondering, "where did migration 201803021132931 come from? Is it something I need to roll back for my current task?" When this happens, I need a way to figure out what the missing migrations do in order to track what work I need to do when I switch contexts. To solve this problem, I created a small Git extension, called [`git-find-migration`][gfm].

## New workflow

My workflow now for tracking these migrations across branches is as follows:

1. I change to the `upstream/master` branch on Git. This gives me the context for the current state of what is running in production (n.b. I don't actually check out `upstream/master`, but I sync my local copy of `master` with it).
2. Then, I run `g fm -l` to list any migrations that have been run, but I am missing on the branch (n.b. I use a [function called `g`][g] and [aliased `git-find-migration` to fm][gfm] to make this easier to type).
3. For each migration that I am missing, I copy the timestamp, then run `g fm <timestamp>` to see the name of the file in my Git repository.
4. Once I know the name of the file, I run `git log --all -- db/migration/<migration_file>` to see the context for that file.

This workflow allows me to easily make decisions to handle the migration. Sometimes, the migration is an old one that has since been pruned from the repository (not a suggested tactic, might I add!) and it's fine. Sometimes, it's something that I should roll back to continue my work. In that case, I check out the branch with the migration and run a `rails db:migrate:down VERSION=<timestamp>` to roll it back<sup id="fn-rollback-return">[1](#fn-rollback)</sup>.

## Shortcomings

I could likely still make some improvements to this workflow. For example, I currently limit my script to searching for only a single timestamp at once. This was because I didn't want to figure out how to write the Git query that could find more than one. Perhaps that would speed along the process when I have several migrations that I need to roll back. This happens a lot when we're working on a multistage, backwards-compatible, destructive change.

Even with these shortcomings, the new workflow serves me well. Feel free to [download the script][gfm] if this sounds interesting! Do you have any techniques for managing migrations across multiple branches?

The post [Finding Rails migrations](https://michaeljherold.com/2018/08/13/finding-rails-migrations/) appeared first on [Michael Herold](https://michaeljherold.com).

<div class="footnotes">
  <ol>
    <li id="fn-rollback">You always make sure your migrations can be rolled back, don't you? <a href="#fn-rollback-return">↩︎</a></li>
  </ol>
</div>

[g]: https://github.com/michaelherold/dotfiles/blob/8b3b472be89487111ddc742921e93f7b79542855/zsh/functions/g
[gfm]: https://github.com/michaelherold/dotfiles/blob/8b3b472be89487111ddc742921e93f7b79542855/bin/git-find-migration