How should I use Mercurial as a lone developer?
Version ControlMercurialVersion Control Problem Overview
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?
Version Control Solutions
Solution 1 - Version Control
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 - Version Control
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: http://hgbook.red-bean.com/hgbook.html">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 - Version Control
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.
Solution 4 - Version Control
I use Mercurial daily, see here, I also help out at one of the few free hosting services that supports Mercurial, ShareSource (I'm on the credits page). I have been using HG since Xen dropped BitKeeper.
I would advise you, for personal projects, avoid branches at all costs. Mercurial's idea of what a branch is differs quite a bit from what you'd expect. Other systems like Git make branching (and mad scientist ideas) a little easier. However, I only use Git when I need easy, cheap branches.
My typical day with hg:
(See where I left off)
# hg status
(See what I was doing with foo)
# hg diff -r tip src/foo/foo.c
(Finish one module, commit it)
# hg commit src/foo/foo.c
(Push changes)
# hg push
Merging is also pretty simple, as well as pulling specific revisions from related repositories. But, if your solo, chances are if get presented with a merge to resolve, you probably screwed up by not updating the remote repo.
I have started a few solo hobby projects that got wildly popular a year after I released them, I'm glad that I used HG. Its syntax is close to subversion, its very intuitive and extremely portable.
Sure, yes, I use Git and SVN .. but not for personal projects. A note on my repo index (the link posted), I re-wrote hgwebdir in PHP because I wanted to modify its look easily and pull RSS from each repo.
In short, for personal use, you'll find it VERY friendly. Commits, tags, etc are simple .. avoid branches unless you really need them.
This is a tutorial that I wrote some time ago describing how to use Mercurial to manage a web site, you might find it of interest when setting up your keys, hgrc, etc.
Solution 5 - Version Control
These are usually the same as you would work on any software project. Simply having or not having version control is beyond any discussion ;)
Usually you just commit when your feature's ready. Since you have a backup you don't need to commit every day just to have your work stored safely.
For branching: in my solo project I use it mainly for trying ideas, eg. when I have another solution for the same problem. For this I also love Git's stash command.
However I do have multiple repositories. I have a hosting with shell access that I push to. So I can sync with that repo no matter where do I work and whatever workstation I have (at work: when I have some time to code, at home desktop and on lappy when at parent's house).
Solution 6 - Version Control
I don't know why you'd want multiple repositories, since you're already backing up your machine where the repository will reside.
And maybe you'll be branching for yourself, if say you want to investigate a feature and don't want to scramble in your main code branch.
But maybe you'll extract something out of a question I posed earlier.
Solution 7 - Version Control
I have used CVS, Perforce, Subversion before as my personal version control system and went to Mercurial since about two weeks ago :-) At work we use MS Team System ...
For me the most notable new thing is easy transfer between different machines. At work I have stuff in a mercurial repo (using hg as a Super-Client against Team System). I regularily push/pull all changes to/from my Laptop so I have a full history at both machines.
At home I also push/pull the repo from the Laptop.
As a result I can work wherever I am (home office using a beefy computer, on the road using the laptop or at work) and not worry whether I will lose changes. Ok, occasionally I need to merge two changes but that rarely hurts ... hg does it quite nicely IMHO.
Additionally, the "setup cost" with mercurial is quite low. You read a tutorial, install it, say "hg init" and go on working. No more decding if something belongs into your sacred SVN server, where to put it and so on. Mercurial's "friction" is a little lower than SVN's.
Solution 8 - Version Control
I think this depends on whether or not you are maintaining an existing application and adding features (or fixing large bugs) at the same time.
This way you can fix bugs in the main branch while creating a new feature in it's own branch.
I do exactly that with my applications, but with a local version of CVS. Also, if a new developer is added to your team, you are all set to go.
I agree that this is a separate issue from backups.
Good Luck,
Randy Stegbauer
Solution 9 - Version Control
The SCM is a sort of "smart" undo buffer extension of your editor. You can go back time, you may have solved a problem, but deleted it, because it has been refactored, but you would need the solution again, etc. Set up a visual diff and it will tell you what you have changed since the last commit or in the last two days, I am constantly reviewing my code and change it if I don't like my old solution.
Branching is working on streams: when you start to go in one direction, but it needs more thinking and in the meantime you would like to work on something else, then it can help.
Be beware that DVCSs handle the repository as a single unit. You can commit file-by-file (using filters), but they store the changes against the whole repository. It confuses cvs (svn) users where single file changes are more regular.
Solution 10 - Version Control
Another excellent reason to have multiple clones (at least if you have more than one computer) is that you quite easily see if you have introduced any dependencies to your code. (I.e. will your code run on another machine, which might not have all the development packages that your primary workstation has)
Solution 11 - Version Control
I suggest you read this link which outlines the various ways you can implement SCC and choose the method that fits mostly with your needs
Solution 12 - Version Control
DVC like Mercurial-- and Bazaar and Git-- have made many things cheaply available such that an army of one can benefit from expanded capabilities.
-
You can quickly experiment with "throwaway" code if you maintain discipline in keeping working branches up to date or off mainline and sync all your deltas meaningfully into the DVC.
The code just flows without worry, and it actually can provide one the mental freedom to try multiple solutions before settling on the preferred one.
-
Some people make branches for each feature they implement (especially in git), regardless of how small or large. In mercurial, this development approach is cheap, so why not use the capability? So this could mean tiny commits with larger commits several times a day.
a. If you adopted this approach you might want to push the changes to an off-host repo at the end of the work day in order to cover the time between work done for the day and time at which backup to WHS occurs.
b. I have installed CopSSH on my WHS and it works wonderfully providing SSH/SFTP/SCP functionality to the windows box in ~5MB. before that I was running Ubuntu Linux on Virtual Server 2005 to provide, among other services, similar functionality. You can push your mercurial to the WHS box over ssh
Solution 13 - Version Control
I always use Git or Mercurial, even alone.
I separate the repositories when I want to make some reusable components available to other projects. I configured out to when I commit, it push automatically too (I did with Tortoise HG plugin), because sometimes I forgot to push, and when move geographically I need that code, understand?
So, this is my tips.