How should I use Mercurial as a lone developer?

I've decided that I want to use Mercurial for a small, personal project.

Most of the help I've read about it talks about merging changes between multiple users. Since I'm solo, that's not going to happen.

Should I have multiple repositories? My development computer is already backed up nightly to my Windows Home Server, so it doesn't seem valuable to have a second repository elsewhere just for backup purposes.

Should I be branching every day? Or just around releases? Or when?

In general, what practices do you recommend for the lone developer using Mercurial?


Solution 1:

I use Mercurial to develop FsCheck, a unit testing framework hosted in codeplex. I am currently the only developer, but occasionally people send me patches.

Concretely, I have one folder in my filesystem called "FsCheck". In that, I have one repository, and thus folder, called main. Typically, I have a few folders next to that where I work on specific features or bug fixes or whatever, say bug-escapingexceptions and feat-statefulchecking and patch-userFoo. These are created using hg clone.

When I'm done with a feature or bugfix, I commit everything in that folder and push to main. Possibly merge in main. (hg commit, hg push, hg merge). Then I delete the folder (careful using hg status and hg outgoing that I'm not throwing away something useful).

I almost never work in main except right before a release, where I do final cleanup (say documentation). Before release, I tag in main with the release number (hg tag v0.5.1).

Codeplex uses svn as sourcecontrol. I only use it as to store releases, for which I use a locally checked out SVN working copy, to which I copy the Mercurial repository using hg archive. Then commit using svn. Primitive, but it works (using Mercurial as an SVN 'super client' on windows isn't very user-friendly yet in my opnion)

I haven't had to do maintenance on previous releases yet, but I would do that by cloning the main repository from that release's revision(this is easy, since I tagged it), and work in that separate repository. Merging back to the main trunk would be as easy as pushing the changes to main and merging.

In summary:

  • One folder to store all your project's repositories, with the name of your project
  • In that folder one main repository, and one transient repository per "unit of work", with a descriptive name for the unit of work.

It's nice cause your branches and what you're working on is intuitively visible in the filesystem.

Solution 2:

From the way your question is worded, I think you may have some misunderstandings related to version control terminology.

You should have a single repository for each project. You can think of a repository simply as a folder on the filesystem. When you initialize a Mercurial repository in a particular folder, every file in that folder and any of its subfolders is eligible to be added to the repository to be version-controlled. You don't necessarily have to add everything, but any of it will be able to be added if you want to.

You can push this local repository to a remote repository if you wish, either as a form of backup or as a method of sharing your code with others. But if it's simply a personal project, this most likely won't be necessary, especially since you already have a backup solution in place.

Branches are typically used for keeping different "versions" of the project separated. As some people have mentioned, this can be useful as a solo developer for trying out a method of refactoring the code, or testing a different approach to a particular problem. If it doesn't work out, you don't have to worry about figuring out where to roll back to, you just torch the branch. If it did work, you merge the branch back into the main repository (the "trunk") and carry on.

If you do get to the point where you make "releases" of the code, and you need to keep maintaining old versions, you'll also want to use branches. For example, imagine that you release version 1.0, and some people start using it. While they're using it, you privately continue working towards the next release, perhaps 1.1, adding features in your trunk repository. Now, someone discovers a bug in the released 1.0 code that you need to fix, but you can't just fix it in the trunk and give them that code, because it's in no state to be released. This is where the 1.0 branch comes in handy. You can fix the bug in the 1.0 branch, and merge the bugfix change into the trunk, so that the bug is fixed there as well. Then you can repackage up 1.0 with the bugfix and get it out to your users, without having to figure out how to get the trunk into a state that it could be released to the public.

Other than that, there's generally not a lot of fancy work involved in using Mercurial solo. Do some work, and when you finish a feature, commit it to give yourself a "checkpoint" that you can come back to in the future if needed. You don't need to commit every time that you save or anything like that, just do it when you feel like you've added something somewhat significant. This will give you a nice history of the project if you ever need to look back through it.

For more information, I highly suggest taking some time to read through this book: Distributed revision control with Mercurial. You don't have to read into the advanced topics, but reading at least chapters 1-5 and 8 will give you a good introduction to Mercurial and version control in general.

Solution 3:

I use another distributed version control system than Mercurial, but I doubt it matters for this.

On my solo projects, I use branching fairly heavily. I typically have a main development branch ("trunk"), which is supposed to have a working version at all times. By that I mean that unit tests and other automated tests pass, and that all code is tested by these tests, except the small bits that I have explicitly excluded from test coverage. This ensures the trunk is always in a good shape for further development.

Whenever I start working on a change, I create a new branch off the trunk branch. This gives me freedom to hack freely. I might not worry about automated tests passing in this branch, for example. Since it is an isolated area, I can commit as often as I like, and I do: microcommits are my favorite feature with distributed version control. When the work in the branch is finished, I merge it back to trunk.

The benefit of this style of working is that if it turns out that the changes I'm working on are a bad idea, I can easily back out. In fact, there is nothing to back out from, since the changes haven't been merged.

Sometimes I am lazy and don't create a new branch for some new thing I'm developing. Invariably it turns out that this is a mistake, when I need more time than I expected to finish the work. It gets worse when I need to do another, unrelated change in the middle of this. When I follow the all-work-in-its-own-branch style, the unrelated change can be done in its own branch, merged into trunk, and then the other branch can merge the change from trunk, if it's needed.