[Solved]-Mercurial: keep 2 branches in sync but with certain persistent differences?


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.


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.


I’ve solved this with local settings.

  1. Append to settings.py:

    from local_settings import *
    except ImportError:

  2. touch local_settings.py

  3. Add ^local_settings.py$ to your .hgignore

Each deploy I do has it’s own local settings (typically different DB stuff and different origin email addresses).

PS: Only read the “minified versions of javascript portion” later. For this, I would suggest a post-update hook and a config setting (like JS_EXTENSION).

Example (from the top of my head! not tested, adapt as necessary):

  1. Put JS_EXTENSION = ‘.raw.js’ in your settings.py file;
  2. Put JS_EXTENSION = ‘.mini.js’ in your local_settings.py file on the production server;
  3. Change JS inclusion from:

    <script type="text/javascript" src="blabla.js"></script>


    <script type="text/javascript" src="blabla{{JS_EXTENSION}}"></script>

  4. Make a post-update hook that looks for *.raw.js and generates .mini.js (minified versions of raw);
  5. Add .mini.js$ to your .hgignore


Perhaps try something like this: (I was just thinking about this issue, in my case it’s a sqlite database)

  • Add settings.py to .hgignore, to keep it out of the repository.
  • Take your settings.py files from the two separate branches and move them into two separate files, settings-prod.py and settings-dev.py
  • Create a deploy script which copies the appropriate settings-X file to settings.py, so you can deploy either way.

If you have a couple of additional files, do the same thing for them. If you have a lot of files but they’re all in the same directory by themselves, you could just create a pair of directories: production and development, and then either copy or symlink the appropriate one into a deploy directory.

If you did something like this, you could dispense with the need for branching your repository.


I actually do this using named branches and straight merging instead of transplanting (which is more reliable, IMO). This usually works, although sometimes (when you’ve edited the different files on the other branch), you’ll need to pay attention not to remove the differences again when you’re merging.

So it works great if you’re not changing the different files much.


Leave a comment