The Problem
When working with Rails migrations across git branches:
- You run migrations on a feature branch
- Switch back to
main - Run
db:migrate- Rails dumps schema including changes from the other branch - You can't rollback because the migration files don't exist in current branch
Usual workaround: Switch to the other branch, rollback, switch back. Tedious.
The Solution
Mighost automatically captures migration file contents when they run, enabling rollback even when the original file is not present. It uses a 3-tier recovery strategy:
- Stored snapshots — captured at migration time into a local SQLite file
- Git history — searches across all branches
- Worktree recovery — finds files in other git worktrees
Installation
Add to your Gemfile:
gem 'mighost', group: [:development, :test]
Then run:
bundle install
rails generate mighost:install
Add .mighost.sqlite3 to your .gitignore.
Requires Ruby >= 3.1 and Rails 6.1–8.1.
Usage
Check for orphaned migrations
rails mighost:status
Rollback orphaned migrations
# Interactive (with confirmation)
rails mighost:rollback
# Force (no confirmation)
FORCE=1 rails mighost:rollback
# Specific version
rails mighost:rollback VERSION=20240115123456
Scan existing migrations & git history
If you install Mighost on an existing project:
rails mighost:scan
All commands
| Command | Description | Options |
|---|---|---|
mighost:status |
Show orphaned migrations | DEBUG=1, SHOW_DISMISSED=1 |
mighost:rollback |
Rollback orphaned migrations | VERSION=x, FORCE=1 |
mighost:scan |
Capture migrations + search git | RESCAN=1 |
mighost:list (ls) |
List stored migration records | LIMIT=N |
mighost:dismiss |
Hide migrations from status | VERSION=x, VERSION=a..b, OLD=1 |
mighost:undismiss |
Restore dismissed migrations | VERSION=x |
mighost:dismissed |
List dismissed migrations | |
mighost:cleanup |
Remove stale records | FORCE=1 |
mighost:help |
Show command reference |
Version ranges
VERSION=20240115123456 # Single version
VERSION=20240110..20240120 # Inclusive range
VERSION=20240110.. # From version onwards
VERSION=..20240120 # Up to version
Configuration
# config/initializers/mighost.rb
Mighost.configure do |config|
# Path to SQLite file (relative to Rails.root)
config.storage_path = ".mighost.sqlite3"
# Auto-capture on migrate
config.auto_capture = true
# Store git metadata
config. = true
# Enable/disable (disabled in production by default)
config.enabled = !Rails.env.production?
end
Rich Output with Railbow
By default, Mighost outputs plain, uncolored text. For rich, colorized output with tables, emojis, and git enrichment, use the railbow gem:
gem 'railbow'
Railbow automatically detects Mighost and enhances its output.
Public API
Mighost exposes a stable API for programmatic access:
# Detect orphaned migrations
Mighost::API.orphaned_migrations # => [OrphanedMigration, ...]
# Find snapshots
Mighost::API.find_snapshot("20240115123456") # => Snapshot or nil
Mighost::API.find_or_recover_snapshot("20240115") # => Snapshot (with git/worktree fallback)
# Scan and recover
Mighost::API.scan!(rescan: false) # => {captured:, git_recovered:, ...}
# Rollback
Mighost::API.rollback_version!("20240115123456") # raises on failure
UI Adapter
Mighost uses a pluggable UI adapter for output. Replace it to customize formatting:
# In your railtie or initializer:
Mighost.ui = YourCustomUI.new
The adapter must implement: render_orphans, render_records, render_recoverable_list, render_scan_details, render_scan_results, render_dismiss_preview, render_dismiss_remaining, render_dismissed_list, confirm?, confirm_each?, confirm_dismiss?, success, error, warning, info, hint. See Mighost::PlainUI for the reference implementation.
How It Works
-
Capture: When you run
db:migrate, Mighost hooks intoActiveRecord::Migratorand stores the migration file content along with git metadata (branch, SHA) in a local SQLite file. -
Detect:
mighost:statuscomparesschema_migrationstable with actual migration files to find orphans. -
Recover: For missing files, Mighost searches stored snapshots, git history (all branches), and other git worktrees.
-
Rollback: Writes recovered content to a temp file, loads it, calls the
downmethod, then removes the version fromschema_migrations.
Limitations
- Irreversible migrations: If the migration raises
ActiveRecord::IrreversibleMigration, Mighost can't help. - Model dependencies: If your migration references models/classes that don't exist in the current branch, the rollback may fail.
- Manual SQL changes: If someone manually modified the database, rollback might not work correctly.
- Trust: Recovered migration code (from snapshots, git history, or worktrees) is executed with the same trust as your own migrations — it is code from your repository, run by you.
Contributing
Bug reports and pull requests are welcome on GitHub. Run bundle exec rake (specs + standardrb) before submitting.
License
MIT License. See LICENSE.