Index: update-stats.py
===================================================================
--- update-stats.py	(revision 386)
+++ update-stats.py	(working copy)
@@ -80,10 +80,17 @@
 
     def __init__(self, module, onlybranch = None):
         self.module = module
-        if module.has_key('cvsroot'):
+#FIXME: Overriding defaults doesn't work properly! This gives preference to the first ones.
+#       for example, if git is defined in defaults and cvsroot needs to override it, it
+#       can't -- you need to explicitely override the default like this: <cvsroot />.
+        if module.has_key('gitroot') and module['gitroot'] != '':
+            COs = modules.GitModule(module, 1)
+        elif module.has_key('hgroot') and module['hgroot'] != '':
+            COs = modules.HgModule(module, 1)
+        elif module.has_key('svnroot') and module['svnroot'] != '':
+            COs = modules.SvnModule(module, 1)
+        elif module.has_key('cvsroot') and module['cvsroot'] != '':
             COs = modules.CvsModule(module, 1)
-        elif module.has_key('svnroot'):
-            COs = modules.SvnModule(module, 1)
         else:
             raise Exception("Can't fetch source code for this module.")
 
Index: modules.py
===================================================================
--- modules.py	(revision 386)
+++ modules.py	(working copy)
@@ -200,6 +200,154 @@
                 print >> sys.stderr, output
             return 0
 
+
+class HgModule:
+    """Checks out a module from Mercurial (hg) if necessary to be able to work on it."""
+
+    def __init__(self, module, real_update = 1):
+        if not module: return None
+
+        self.paths = {}
+        self.module = module
+
+        localroot = os.path.join(defaults.scratchdir, "hg")
+        branches = module["branch"].keys()
+        for branch in branches:
+            moduledir = module["id"] + "." + branch
+            checkoutpath = os.path.join(localroot, module["id"] + "." + branch)
+
+            if real_update:
+                if defaults.DEBUG:
+                    print >>sys.stderr, "Checking '%s.%s' out to '%s'..." % (module["id"], branch, checkoutpath)
+                co = self.checkout(module["hgroot"],
+                                   module["hgmodule"], branch, 
+                                   localroot,
+                                   moduledir)
+
+                if not co:
+                    print >> sys.stderr, "Problem checking out module %s.%s" % (module["id"], branch)
+                else:
+                    self.paths[branch] = checkoutpath
+            else:
+                if os.access(checkoutpath, os.X_OK):
+                    self.paths[branch] = checkoutpath
+
+
+    def checkout(self, hgroot, module, branch, localroot, moduledir):
+
+        import commands
+
+        try: os.makedirs(localroot)
+        except: pass
+
+        commandList=[]
+        if os.access(os.path.join(localroot, moduledir), os.X_OK | os.W_OK):
+            commandList.append("cd %(localdir)s && hg update %(branch)s" % {
+                "localdir" : os.path.join(localroot, moduledir),
+                "branch" : branch,
+                })
+        else:
+            hgpath = hgroot + "/" + module
+            commandList.append("cd %(localroot)s && hg clone %(hgpath)s %(dir)s" % {
+                "localroot" : localroot,
+                "hgpath" : hgpath,
+                "dir" : moduledir,
+                })
+            commandList.append("cd %(localdir)s && hg update %(branch)s" % {
+                "localdir" : os.path.join(localroot, moduledir),
+                "hgpath" : hgpath,
+                "branch" : branch,
+                })
+        errorsOccured = 0
+        for command in commandList:
+            if defaults.DEBUG:
+                print >>sys.stdout, command
+            (error, output) = commands.getstatusoutput(command)
+            if defaults.DEBUG:
+                print >> sys.stderr, output
+            if error:
+                errorsOccured = 1
+            if error and defaults.DEBUG:
+                print >> sys.stderr, error
+        if errorsOccured:
+            return 0
+        else:
+            return 1
+            
+class GitModule:
+    """Checks out a module from git if necessary to be able to work on it."""
+
+    def __init__(self, module, real_update = 1):
+        if not module: return None
+
+        self.paths = {}
+        self.module = module
+
+        localroot = os.path.join(defaults.scratchdir, "git")
+        branches = module["branch"].keys()
+        for branch in branches:
+            moduledir = module["id"] + "." + branch
+            checkoutpath = os.path.join(localroot, module["id"] + "." + branch)
+
+            if real_update:
+                if defaults.DEBUG:
+                    print >>sys.stderr, "Checking '%s.%s' out to '%s'..." % (module["id"], branch, checkoutpath)
+                co = self.checkout(module["gitroot"],
+                                   module["gitmodule"], branch, 
+                                   localroot,
+                                   moduledir)
+
+                if not co:
+                    print >> sys.stderr, "Problem checking out module %s.%s" % (module["id"], branch)
+                else:
+                    self.paths[branch] = checkoutpath
+            else:
+                if os.access(checkoutpath, os.X_OK):
+                    self.paths[branch] = checkoutpath
+
+
+    def checkout(self, gitroot, module, branch, localroot, moduledir):
+
+        import commands
+
+        try: os.makedirs(localroot)
+        except: pass
+
+        commandList=[]
+        if os.access(os.path.join(localroot, moduledir), os.X_OK | os.W_OK):
+            commandList.append("cd %(localdir)s && git checkout %(branch)s" % {
+                "localdir" : os.path.join(localroot, moduledir),
+                "branch" : branch,
+                })
+        else:
+            gitpath = gitroot + "/" + module
+            commandList.append("cd %(localroot)s && git clone %(gitpath)s %(dir)s" % {
+                "localroot" : localroot,
+                "gitpath" : gitpath,
+                "dir" : moduledir,
+                })
+            commandList.append("cd %(localdir)s && git checkout %(branch)s" % {
+                "localdir" : os.path.join(localroot, moduledir),
+                "gitpath" : gitpath,
+                "branch" : branch,
+                })
+        errorsOccured = 0
+        for command in commandList:
+            if defaults.DEBUG:
+                print >>sys.stdout, command
+            (error, output) = commands.getstatusoutput(command)
+            if defaults.DEBUG:
+                print >> sys.stderr, output
+            if error:
+                errorsOccured = 1
+            if error and defaults.DEBUG:
+                print >> sys.stderr, error
+        if errorsOccured:
+            return 0
+        else:
+            return 1
+
+
 if __name__=="__main__":
     m = XmlModules()
     import pprint
