Skip to content

Instantly share code, notes, and snippets.

@joelmoss
Created September 9, 2021 07:11
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 joelmoss/75eac8ccfb79a820ec3fde3a625faf8a to your computer and use it in GitHub Desktop.
Save joelmoss/75eac8ccfb79a820ec3fde3a625faf8a to your computer and use it in GitHub Desktop.
post-checkout git hook to switch Rails DB along with the branch
#!/usr/bin/env ruby
require 'yaml'
# Return if this is not a branch checkout.
return if ARGV[2] != '1'
def drop_existing_connections_to_database(database_name)
system(%[psql --command="SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '#{database_name}' AND pid <> pg_backend_pid();" postgres > /dev/null])
end
def branches_from_refhead(ref)
`git show-ref --heads | grep #{ref} | awk '{print $2}'`.split("\n").map do |b|
b.sub(%r{^refs/heads/}, '')
end
end
# Get the current (destination) branch
dest_branch = `git rev-parse --abbrev-ref HEAD`.strip
# Since we're just given a commit ID referencing the branch head we're coming from,
# it could be at the head of multiple branches. We can assume the source isn't the same as the
# destination branch, so we can remove that immediately.
source_branches = branches_from_refhead(ARGV[0]).reject { |b| b == dest_branch }
project_root = `git rev-parse --show-toplevel`.strip
# Load Rails DB config and grab database name
rails_db_config = YAML.load_file("#{project_root}/config/database.yml")
dev_db = rails_db_config['development']['database']
# Don't do anything if the source and destination branches are the same or nonexistent
return if source_branches.include?(dest_branch) || source_branches.empty? ||
(source_branches | [dest_branch]).any?('')
puts "Switching development database from #{source_branches.join(', ')} to #{dest_branch}..."
# Drop connections
drop_existing_connections_to_database dev_db
# Copy dev DB to source branches
source_branches.each do |br|
print " -- Copying #{dev_db} to #{dev_db}__#{br} ..."
if `psql -tAc "SELECT 1 FROM pg_database WHERE datname='#{dev_db}__#{br}'"`.strip == '1'
print ' (dropping existing one first)'
system %(dropdb #{dev_db}__#{br})
end
system "createdb -T #{dev_db} #{dev_db}__#{br}"
puts ' DONE'
end
if `psql -tAc "SELECT 1 FROM pg_database WHERE datname='#{dev_db}__#{dest_branch}'"`.strip == '1'
print " -- Dropping #{dev_db} ..."
system %(dropdb #{dev_db})
puts ' DONE'
# Rename destination branch DB to dev DB
print " -- Renaming #{dev_db}__#{dest_branch} to #{dev_db} ..."
system %(psql --command="ALTER DATABASE #{dev_db}__#{dest_branch} RENAME TO #{dev_db};" postgres > /dev/null)
puts ' DONE'
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment