Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mercurial: keep 2 branches in sync but with certain persistent differences?

I'm a web developer working on my own using django, and I'm trying to get my head round how best to deploy sites using mercurial. What I'd like to have is to be able to keep one repository that I can use for both production and development work. There will always be some differences between production/development (e.g. they might use different databases, development will always have debug turned on) but by and large they will be in sync. I'd also like to be able to make changes directly on the production server (tidying up html or css, simple bugfixes etc.).

The workflow that I intend to use for doing this is as follows:

  • Create 2 branches, prod and dev (all settings initially set to production settings)
  • Change settings.py and a few other things in the dev branch. So now I've got 2 heads, and from now on the repository will always have 2 heads.
  • (On dev machine) Make changes to dev, then use 'hg transplant' to copy relevant changesets to production.
  • push to master repository
  • (On production server) Pull from master repo, update to prod head

Note: you can also make changes straight to prod so long as you transplant the changes into dev.

This workflow has the drawback that whenever you make a change, not only do you have to commit it to whichever branch you make the change on, you also have to transplant it to the other branch. Is there a more sensible way of doing what I want here, perhaps using patches? Or failing that, is there a way of automating the commit process to automatically transplant the changeset to the other branch, and would this be a good idea?

like image 474
markmuetz Avatar asked Aug 10 '09 15:08

markmuetz


2 Answers

I'd probably use Mercurial Queues for something like this. Keep the main repository as the development version, and have a for-production patch that makes any necessary changes for production.

like image 128
Steve Losh Avatar answered Nov 16 '22 00:11

Steve Losh


Here are two possible solutions one using mercurial and one not using mercurial:

  1. Use the hostname to switch between prod and devel. We have a single check at the top of our settings file that looks at the SERVER_NAME environment variable. If it's www.production.com it's the prod DB and otherwise it picks a specified or default dev/test/stage DB.
  2. Using Mercurial, just have a clone that's dev and a clone that's prod, make all changes in dev, and at deploy time pull from dev to prod. After pulling you'll have 2 heads in prod diverging from a single common ancestor (the last deploy). One head will have a single changeset containing only the differences between dev and prod deployments, and the other will have all the new work. Merge them in the prod clone, selecting the prod changes on conflict of course, and you've got a deployable setup, and are ready to do more work on 'dev'. No need to branch, transplant, or use queues. So long as you never pull that changeset with the prod settings into 'dev' it will always need a merge after pulling from dev, and if it's just a few lines there's not much to do.
like image 31
Ry4an Brase Avatar answered Nov 16 '22 00:11

Ry4an Brase