>>2010-07-10>> Mercurial: Branching, Cloning and Revisions, oh my! Part Three 

This is the third article in a series where I discuss how I dealt with the challenge of maintaining two separate but similar web sites in source control. This kind of scenario doesn’t really follow the Version->Maintenance->Next Version linear development process. Instead, it has common code and separate themes.

In article one, I talked about your choices in how to work with this kind of structure.

In article two, I talked about how to use the Convert extension to split the common code out of our database.

In this article, I’m going to talk about the third and least friendly choice:

Finally, if you believe that the common code will change infrequently, you can avoid site merges and instead use the hg export and import commands to merge only certain transactions to the other branch. This last choice may seem the most expedient – especially if you’ll have many small differences in the common code – but it’s also the most error prone. Should another developer accidentally do a push and merge, you’d better know how to recover from it.

First an important note! This use case is by far the most error prone and I’d advise you to avoid it if you can. I’m mostly using it as an example to showcase the Mercurial import and export functionality. That being said, if you’re a solo developer short on time and you know what you’re doing, you may find this to be the most convenient way of handling this problem.

First we have to create a branch for the new site. In Mercurial we have two choices: branching or cloning. They both pretty much achieve the same goal but your development goals may differ:

  • Cloning allows you to create a second directory and copy all of the changes over to it. The upside is that it’s super easy to implement. The downside is that if you have remote workers who use both branches, they’ll have to download twice as much code to use it. No big deal for small sites, but it’s nasty issue with larger ones. In addition, separate repositories can get confusing and you might forget to move code back and forth.
  • Branching allows you to work with both branches in the same repository. This ensures that you’ll always have the changes in one place, but it means your developers will have to remember to switch the branch when they are making changes to each site.

For today’s example, I’m going to choose the cloning method since it’s somewhat easier to maintain.

For ease of use, I’m going to tag the current version of my database. This will allow me to easily see where I branched off in the future should I need to introduce a third web site.

# cd original_repo
# hg tag BRANCH_POINT

Now I’m going to clone the first repository:

# cd ..
# clone original_repo new_repo
requesting all changes
adding changesets
adding manifests
adding file changes
added 62 changesets with 1451 changes to 583 files
updating to branch default
569 files updated, 0 files merged, 0 files removed, 0 files unresolved

Now we have two separate databases: original_repo and new_repo. Go ahead and change both sites to your heart’s content. But there’s going to come a time when you’ll need to share common code changes between the two repositories. Don’t push changes to the other site! If you do, you’ll get all the code changes in your other site’s next update. That will surely be a drag to fix. Now you can get around this by creating branches inside the repositories, but that’s more complicated so we’re leaving it out for now.

Instead, make sure your common code changes are saved in a separate transaction from any thematic changes. Then you can use the Mercurial export command to move just those changes to your second database. Here’s an example. Say you made a common change to a file called “store.php”. First, diff the file to ensure that only common code changes have been made to it since the last check-in:

# cd original_repo
# hg diff store.php

Looking good? Perfect! Now check in that change and then use the log command to see its transaction:

# hg ci -m “Update to common code” store.php
# hg log store.php
changeset:   67:fee9849d0721
branch:      default
tag:         tip
user:        Sean <sean@localhost>
date:        Sat Jun 12 11:50:53 2010 -0700
summary:     Update to common code

There we go – the specific transaction for this change is 67. Now use the export command to save just that transaction to a file:

# hg export -r 67 > change.txt

The export command creates a patch file with the changes you made.

Note: Only the changes made in this specific transaction will be included! If you made other changes to the file earlier, they will not be included. You may have to manually merge this change if your files now greatly differ from each other. Yes… that’s just one more reason why you shouldn’t use this particular option if you can help it.

Head over to your other database and import the change:

# cd ../new_repo
# import ../original_repo/change.txt

Tada! The change is made in both databases. Don’t forget to look at the code to make sure that the change was made as you expected it to be.

And that ends this Mercurial series. Let me know if you’d like me to write more articles on Mercurial in the future.

Leave a Reply