From LuxRender Wiki
Mercurial is a Distributed Version Control System. It allows you to easily store a complete copy of the repository on your local machine and maintain local changes in it while at the same time tracking the official development. Mercurial is now the official Version Control System for the LuxRender project and you can access it through a web portal.
Mercurial should be available through the package system of most Linux distributions. If not available precompiled on your system, you can have a look at Mercurial download page. There are also various utilities integrating Mercurial in your workflow, some are referenced in Mercurial tools page.
Note for Windows users: We use Unix EOL encoding for the files in our repositories. In order to get DOS EOL encoding (used by Windows), you can use the built-in Win32TextExtension. See this page for more details on how to enable and configure it.
Obtaining LuxRender Through Mercurial
If mercurial is installed, you should be able to clone the LuxRender repository by issuing the following command:
hg clone http://src.luxrender.net/lux lux
This will put the repository in the subdirectory lux of your current directory. This directory contains all the files from the most recent version of the LuxRender source code and a directory called .hg. To learn what to do from here, see the Mercurial tutorial or Mercurial for CVS users.
Working with Mercurial
Modifying the code and recording the changes
Once you've cloned the repository locally you can start working on lux render. After you've done some modifications, you can record them into the history:
You can eventually specify which file should be considered and some tools allow you to only commit a subset of the changes you've done to a single file. Contrary to CVS, Mercurial commit will associate all file changes together and change the revision of the whole repository, not the revision of each single file. So if your change is a well defined feature, it will be easy to see all modifications you've done and to back them out if they prove inadequate. Actually, commiting well defined features or changes is the preferred way of working with Mercurial.
Getting new changes from the master repository (or another one)
To get changes that others might have done, you need to issue the following command:
This will just add new changes to you local history, it won't update any other file. When you've commited all your changes, you can merge your local chanegs with the changes that you've just incorporated:
If any conflict arises, Mercurial will tell you so that you can check and fix them. Once everything is ok, you need to record the merge operation with a normal commit.
If you hadn't done any change you can use the following shortcut to get the new changes and update your files at once:
hg pull -u
Publishing your changes
Up to now, you've not publish any change to others, all your work has been done locally. So you need to push this work to the main repository:
If some changes are pending upstream that aren't yet in your local repository, the push will abort and ask you to pull and merge first.
If you have followed the above advice to commit well defined changes, mercurial has a very usefull tool call bisect that will allow you to quickly find which change introduced a bug.
If the current revision (let's say it's 20) is wrong and revision 10 is good, issue the following commands:
hg bisect -r #reset the bisect engine hg bisect -b #tell the current revision is bad hg bisect -g 10 #tell that revision 10 is good
Mercurial will then automatically update to revision 15 so that you can check if it works. Depending on the result, issue either:
hg bisect -b #if the current revision is bad hg bisect -g #if the current revision is good
and continue up until Mercurial tells you which change is the culprit. In case you can't make sense of a commit because just skip the revision:
hg bisect -s #skip a revision which isn't in a workable state
If you needed to make some changes to check the revision, you have to restore a clean state before invoking bisect, otherwise it won't automatically update:
hg update -C #restore a clean state of the current revision
If you forgot, you can force an update to the next revision mercurial had chosen:
hg update -C -r 12 #force a clean update to revision 12
When getting new changes, mercurial will require a clean repository to update. So you may loose your modifications. Mercurial also has no way to undo changes to the history, except the last one, which can be bad if you had commited changes and you find they aren't worth keeping. To circumvent those problems, you can do a local clone of the repository. Let say you had cloned the official repository in directory lux, you can the do a local clone in directory lux-working with the command:
hg clone lux lux-working
This will recreate a repository, butt it will try to use links instead of file copies so this won't take as much space as the first repository. You can then work in lux-working and continue to track upstream changes in lux. You can eventually trash your lux-working directory or even create another local clone to work on another feature. When you're done, you'll either be able to push your working repository into the tracking one, then merge, commit and publish it to the main repository:
hg pull #pull new changes from tracking repository hg merge #merge them with the new feature hg push #push the result to the tracking repository cd ../lux #go to the tracking repository hg push #publish changes to the main repository
Or you can use the working repository to create patches and import them into the tracking one:
hg export ... #export the changes you're interested in cd ../lux hg import ... #import the patches hg push #publish the changes
This last method allows you to rewrite the history of the feature while the first method will preserve it.
There's also an extension called Mercurial queues that allows you to keep a stack of patches like quilt. This can be usefull if you have local changes that you want to apply on each new version (like compilation flags) but don't want to impose on everybody else. This is also a very flexible way to have a rewritable history.