Skip to content

Instantly share code, notes, and snippets.

@knu
Last active January 26, 2022 13:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save knu/afb58fa7b7bc2faeaf469e0e37f6d4a6 to your computer and use it in GitHub Desktop.
Save knu/afb58fa7b7bc2faeaf469e0e37f6d4a6 to your computer and use it in GitHub Desktop.
git-rails-db-rollback: Run rails db:rollback before switching to another branch
[alias]
main = "!set -e; p=refs/remotes/origin; if r=\"$(git symbolic-ref $p/HEAD 2>/dev/null)\"; then echo \"${r#$p/}\"; exit; fi; printf %s \"Fixing the broken ref $p/HEAD... \" >&2; if r=\"$(git remote show origin | awk '/^ HEAD branch: /{print $3}')\"; then echo done. >&2; echo \"$r\"; git symbolic-ref \"$p/HEAD\" \"$p/$r\"; else echo failed. >&2; exit 1; fi"
rails-db-rollback = "!sh -ec 'git diff --name-only --diff-filter=A \"${1-$(git main)}\" -- db/migrate | ruby -e \"puts \\$<.read.scan(%r{/([0-9]+)_})\" | sort -r | while read v; do rake db:migrate:down VERSION=$v; done' ."

git-rails-db-rollback

When you are on a feature branch of a Rails application with new migrations, you need to roll them back before you can resume work on another branch. However, this tends to be a tedious job and usually has to be done manually either by doing the following:

  • Running rails db:rollback STEP=<n> if your new migrations are all at the bottom; this may not always be the case if you pulled in changes from another branch where new migrations are added

  • Checking out which versions are specific to the current branch and running rails db:migrate:down VERSION=<version> one by one

git rails-db-rollback does the latter for you.

Usage

git rails-db-rollback [<branch>]
% git rails db-rollback
...migrations...
% git switch -
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

% git rails db-rollback feature/another
...migrations...
% git switch feature/another
Switched to branch 'feature/another'
Your branch is up to date with 'origin/feature/another'.
% rails db:migrate
...

If no branch is given, the default branch of the origin remote is assumed, obtained via git main.

git main
git config --global alias.main '!set -e; p=refs/remotes/origin; if r="$(git symbolic-ref $p/HEAD 2>/dev/null)"; then echo "${r#$p/}"; exit; fi; printf %s "Fixing the broken ref $p/HEAD... " >&2; if r="$(git remote show origin | awk '\''/^ HEAD branch: /{print $3}'\'')"; then echo done. >&2; echo "$r"; git symbolic-ref "$p/HEAD" "$p/$r"; else echo failed. >&2; exit 1; fi'
git config --global alias.rails-db-rollback '!sh -ec '\''git diff --name-only --diff-filter=A "${1-$(git main)}" -- db/migrate | ruby -e "puts \$<.read.scan(%r{/([0-9]+)_})" | sort -r | while read v; do rake db:migrate:down VERSION=$v; done'\'' .'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment