diff --git a/jhbuild/config.py b/jhbuild/config.py
index b636db3..f6431d9 100644
--- a/jhbuild/config.py
+++ b/jhbuild/config.py
@@ -44,7 +44,7 @@ _known_keys = [ 'moduleset', 'modules', 'skip', 'tags', 'prefix',
                 'interact', 'buildscript', 'nonetwork',
                 'alwaysautogen', 'nobuild', 'makeclean', 'makecheck', 'module_makecheck',
                 'use_lib64', 'tinderbox_outputdir', 'sticky_date',
-                'tarballdir', 'pretty_print', 'svn_program', 'makedist',
+                'tarballdir', 'pretty_print', 'svn_program', 'git_command', 'makedist',
                 'makedistcheck', 'nonotify', 'notrayicon', 'cvs_program',
                 'checkout_mode', 'copy_dir', 'module_checkout_mode',
                 'build_policy', 'trycheckout', 'min_time',
@@ -151,6 +151,7 @@ class Config:
 
         if not self._orig_environ:
             self.__dict__['_orig_environ'] = os.environ.copy()
+            os.environ['UNMANGLED_PATH'] = os.environ.get('PATH', '')
 
         try:
             SRCDIR
diff --git a/jhbuild/defaults.jhbuildrc b/jhbuild/defaults.jhbuildrc
index badf516..4caf41a 100644
--- a/jhbuild/defaults.jhbuildrc
+++ b/jhbuild/defaults.jhbuildrc
@@ -127,6 +127,11 @@ svn_program = 'svn'
 # program to use for cvs
 cvs_program = 'cvs'
 
+# how to run git. Currently git on Windows is best run from its own
+# MSYS environment with this sort of pattern:
+#  c:\\tools\\git\\bin\\sh.exe -c "/c/tools/git/bin/git.exe %s"
+git_command = 'git %s'
+
 # try and use mirrors?
 mirror_policy = ""
 module_mirror_policy = {}
diff --git a/jhbuild/versioncontrol/git.py b/jhbuild/versioncontrol/git.py
index b2db93a..0e95329 100644
--- a/jhbuild/versioncontrol/git.py
+++ b/jhbuild/versioncontrol/git.py
@@ -50,11 +50,17 @@ if 'git+ssh' not in urlparse.uses_relative:
 if 'ssh' not in urlparse.uses_relative:
     urlparse.uses_relative.append('ssh')
 
-def get_git_extra_env():
+def get_git_extra_env(config):
     # we run git without the JHBuild LD_LIBRARY_PATH and PATH, as it can
     # lead to errors if it picks up jhbuilded libraries, such as nss
-    return { 'LD_LIBRARY_PATH': os.environ.get('UNMANGLED_LD_LIBRARY_PATH'),
-             'PATH': os.environ.get('UNMANGLED_PATH')}
+    env = { 'LD_LIBRARY_PATH': os.environ.get('UNMANGLED_LD_LIBRARY_PATH'),
+            'PATH': os.environ.get('UNMANGLED_PATH') }
+
+    # we use a custom git config file on windows to forcefully disable crlf conversion
+    if sys.platform.startswith('win'):
+        env['GIT_CONFIG'] = config.checkoutroot + '/jhbuild.gitconfig'
+
+    return env
 
 
 class GitUnknownBranchNameError(Exception):
@@ -74,6 +80,7 @@ class GitRepository(Repository):
         Repository.__init__(self, config, name)
         # allow user to adjust location of branch.
         self.href = config.repos.get(name, href)
+        self.git_command = config.git_command
 
     branch_xml_attrs = ['module', 'subdir', 'checkoutdir', 'revision', 'tag']
 
@@ -118,6 +125,21 @@ class GitBranch(Branch):
         self.branch = branch
         self.tag = tag
         self.unmirrored_module = unmirrored_module
+        self.git_command = repository.git_command
+        
+        if self.git_command.find('%s')==-1:
+            self.git_command += ' %s'
+
+        if sys.platform.startswith('win') and \
+                not os.path.exists(os.path.join(self.config.checkoutroot,
+                                   'jhbuild.gitconfig')):
+            cmd = self.make_git_command(['config', '--add', 'core.autocrlf', 'input'])
+            get_output(cmd, extra_env=get_git_extra_env(self.config))
+
+
+    def make_git_command(self, param_list):
+        # Convert params to a string so we can insert them into list. This isn't very nice.
+        return self.git_command % (' '.join(param_list))
 
     def srcdir(self):
         path_elements = [self.checkoutroot]
@@ -132,13 +154,13 @@ class GitBranch(Branch):
 
     def local_branch_exist(self, branch, buildscript=None):
         try:
-            cmd = ['git', 'show-ref', '--quiet', '--verify', 'refs/heads/' + branch]
+            cmd = self.make_git_command(['show-ref', '--quiet', '--verify', 'refs/heads/' + branch])
             if buildscript:
                 buildscript.execute(cmd, cwd=self.get_checkoutdir(),
-                        extra_env=get_git_extra_env())
+                        extra_env=get_git_extra_env(self.config))
             else:
                 get_output(cmd, cwd=self.get_checkoutdir(),
-                        extra_env=get_git_extra_env())
+                        extra_env=get_git_extra_env(self.config))
         except CommandError:
             return False
         return True
@@ -148,21 +170,21 @@ class GitBranch(Branch):
     branchname = property(branchname)
 
     def get_current_branch(self):
-        for line in get_output(['git', 'branch'],
-                cwd=self.get_checkoutdir(), extra_env=get_git_extra_env()).splitlines():
+        for line in get_output(self.make_git_command(['branch']),
+                cwd=self.get_checkoutdir(), extra_env=get_git_extra_env(self.config)).splitlines():
             if line[0] == '*':
                 return line[2:]
         return None
 
     def get_remote_branches_list(self):
-        return [x.strip() for x in get_output(['git', 'branch', '-r'],
+        return [x.strip() for x in get_output(self.make_git_command(['branch', '-r']),
                 cwd=self.get_checkoutdir(),
-                extra_env=get_git_extra_env()).splitlines()]
+                extra_env=get_git_extra_env(self.config)).splitlines()]
 
     def exists(self):
         try:
-            refs = get_output(['git', 'ls-remote', self.module],
-                    extra_env=get_git_extra_env())
+            refs = get_output(self.make_git_command(['ls-remote', self.module]),
+                    extra_env=get_git_extra_env(self.config))
         except:
             return False
 
@@ -171,12 +193,12 @@ class GitBranch(Branch):
         return True
 
     def _get_commit_from_date(self):
-        cmd = ['git', 'log', '--max-count=1',
-               '--until=%s' % self.config.sticky_date]
+        cmd = self.make_git_command(['log', '--max-count=1',
+               '--until=%s' % self.config.sticky_date])
         cmd_desc = ' '.join(cmd)
         proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                 cwd=self.get_checkoutdir(),
-                                env=get_git_extra_env())
+                                env=get_git_extra_env(self.config))
         stdout = proc.communicate()[0]
         if not stdout.strip():
             raise CommandError(_('Command %s returned no output') % cmd_desc)
@@ -193,12 +215,12 @@ class GitBranch(Branch):
 
     def _update_submodules(self, buildscript):
         if os.path.exists(os.path.join(self.get_checkoutdir(), '.gitmodules')):
-            cmd = ['git', 'submodule', 'init']
-            buildscript.execute(cmd, cwd=self.get_checkoutdir(),
-                    extra_env=get_git_extra_env())
-            cmd = ['git', 'submodule', 'update']
+            cmd = self.make_git_command(['submodule', 'init'])
+            buildscript.execute(cmd, cwd=self.get_checkoutdir(), 
+                                extra_env=get_git_extra_env(self.config))
+            cmd = self.make_git_command(['submodule', 'update'])
             buildscript.execute(cmd, cwd=self.get_checkoutdir(),
-                    extra_env=get_git_extra_env())
+                                extra_env=get_git_extra_env(self.config))
 
     def update_dvcs_mirror(self, buildscript):
         if not self.config.dvcs_mirror_dir:
@@ -208,16 +230,15 @@ class GitBranch(Branch):
                 os.path.basename(self.module) + '.git')
 
         if os.path.exists(mirror_dir):
-            buildscript.execute(['git', 'fetch'], cwd=mirror_dir,
-                    extra_env=get_git_extra_env())
+            buildscript.execute(self.make_git_command(['fetch']), cwd=mirror_dir,
+                                extra_env=get_git_extra_env(self.config))
         else:
             buildscript.execute(
-                    ['git', 'clone', '--mirror', self.unmirrored_module],
+                    self.make_git_command(['clone', '--mirror', self.unmirrored_module]),
                     cwd=self.config.dvcs_mirror_dir,
-                    extra_env=get_git_extra_env())
+                    extra_env=get_git_extra_env(self.config))
 
     def _checkout(self, buildscript, copydir=None):
-
         if self.config.quiet_mode:
             quiet = ['-q']
         else:
@@ -225,22 +246,24 @@ class GitBranch(Branch):
 
         self.update_dvcs_mirror(buildscript)
 
-        cmd = ['git', 'clone'] + quiet + [self.module]
+        cmd_list = ['clone'] + quiet + [self.module]
         if self.checkoutdir:
-            cmd.append(self.checkoutdir)
+            cmd_list.append(self.checkoutdir)
+        cmd = self.make_git_command(cmd_list)
 
         if copydir:
-            buildscript.execute(cmd, cwd=copydir, extra_env=get_git_extra_env())
+            buildscript.execute(cmd, cwd=copydir, extra_env=get_git_extra_env(self.config))
         else:
             buildscript.execute(cmd, cwd=self.config.checkoutroot,
-                    extra_env=get_git_extra_env())
+                    extra_env=get_git_extra_env(self.config))
 
         self._update(buildscript, copydir=copydir, update_mirror=False)
 
 
     def _update(self, buildscript, copydir=None, update_mirror=True):
         cwd = self.get_checkoutdir()
-        git_extra_args = {'cwd': cwd, 'extra_env': get_git_extra_env()}
+
+        git_extra_args = {'cwd': cwd, 'extra_env': get_git_extra_env(self.config)}
 
         if not os.path.exists(os.path.join(cwd, '.git')):
             if os.path.exists(os.path.join(cwd, '.svn')):
@@ -256,14 +279,14 @@ class GitBranch(Branch):
             self.update_dvcs_mirror(buildscript)
 
         stashed = False
-        if get_output(['git', 'diff'], **git_extra_args):
+        if get_output(self.make_git_command (['diff']), **git_extra_args):
             stashed = True
-            buildscript.execute(['git', 'stash', 'save', 'jhbuild-stash'],
+            buildscript.execute(self.make_git_command(['stash', 'save', 'jhbuild-stash']),
                     **git_extra_args)
 
         would_be_branch = self.branch or 'master'
         if self.tag:
-            buildscript.execute(['git', 'checkout', self.tag], **git_extra_args)
+            buildscript.execute(self.make_git_command(['checkout', self.tag]), cwd=cwd)
         else:
             current_branch = self.get_current_branch()
             if current_branch != would_be_branch or current_branch == '(no branch)':
@@ -274,53 +297,59 @@ class GitBranch(Branch):
                 # a local work branch, and it won't be changed
                 if ('origin/' + current_branch) in self.get_remote_branches_list():
                     if self.local_branch_exist(would_be_branch, buildscript):
-                        buildscript.execute(['git', 'checkout', would_be_branch],
-                                **git_extra_args)
+                        buildscript.execute(self.make_git_command(['checkout', would_be_branch]),
+                             **git_extra_args)
                     else:
-                        buildscript.execute(['git', 'checkout', '--track', '-b',
-                            would_be_branch, 'origin/' + would_be_branch],
+                        buildscript.execute(self.make_git_command(['checkout', '--track', '-b',
+                            would_be_branch, 'origin/' + would_be_branch]), 
                             **git_extra_args)
 
         current_branch = self.get_current_branch()
         if current_branch != '(no branch)':
-            buildscript.execute(['git', 'pull', '--rebase'], **git_extra_args)
+            buildscript.execute(self.make_git_command(['pull', '--rebase']), **git_extra_args)
 
         if stashed:
             # git stash pop was introduced in 1.5.5, 
-            if check_version(['git', '--version'],
-                         r'git version ([\d.]+)', '1.5.5',
-                         extra_env=get_git_extra_env()):
-                buildscript.execute(['git', 'stash', 'pop'], **git_extra_args)
+            if check_version(self.make_git_command(['--version']),
+                         r'git version ([\d.]+)', '1.5.5'):
+                buildscript.execute(self.make_git_command(['stash', 'pop']), **git_extra_args)
             else:
-                buildscript.execute(['git', 'stash', 'apply', 'jhbuild-stash'],
-                        **git_extra_args)
+                buildscript.execute(self.make_git_command(['stash', 'apply', 'jhbuild-stash']), 
+                         *git_extra_args)
 
         if self.config.sticky_date:
             commit = self._get_commit_from_date()
             branch = 'jhbuild-date-branch'
-            branch_cmd = ['git', 'checkout'] + quiet + [branch]
+            branch_cmd = self.make_git_command(['checkout'] + quiet + [branch])
             try:
                 buildscript.execute(branch_cmd, **git_extra_args)
             except CommandError:
-                branch_cmd = ['git', 'checkout'] + quiet + ['-b', branch]
+                branch_cmd = self.make_git_command(['checkout'] + quiet + ['-b', branch])
                 buildscript.execute(branch_cmd, **git_extra_args)
-            buildscript.execute(['git', 'reset', '--hard', commit], **git_extra_args)
+            buildscript.execute(self.make_git_command(['reset', '--hard', commit]), **git_extra_args)
 
         self._update_submodules(buildscript)
 
 
     def checkout(self, buildscript):
-        if not inpath('git', os.environ['PATH'].split(os.pathsep)):
-            raise CommandError(_('%s not found') % 'git')
+        if self.git_command == 'git %s':
+            if not inpath(self.git_command, os.environ['PATH'].split(os.pathsep)):
+                raise CommandError(_('git not found'))
+        else:
+            git_test_command = self.make_git_command(['--version'])
+            try:
+                get_output (git_test_command, extra_env=get_git_extra_env(self.config))
+            except Exception, e:
+                raise CommandError("running git command '%s': %s" % (git_test_command, e))
         Branch.checkout(self, buildscript)
 
     def tree_id(self):
         if not os.path.exists(self.get_checkoutdir()):
             return None
         try:
-            output = get_output(['git', 'rev-parse', 'HEAD'],
+            output = get_output(self.make_git_command(['rev-parse', 'HEAD']),
                     cwd = self.get_checkoutdir(), get_stderr=False,
-                    extra_env=get_git_extra_env())
+                    extra_env=get_git_extra_env(self.config))
         except CommandError:
             return None
         except GitUnknownBranchNameError:
@@ -363,8 +392,8 @@ class GitSvnBranch(GitBranch):
             # we couldn't find an unhandled.log to parse so try
             # git svn show-externals - note this is broken in git < 1.5.6
             try:
-                output = get_output(['git', 'svn', 'show-externals'], cwd=cwd,
-                        extra_env=get_git_extra_env())
+                output = get_output(self.make_git_command(['svn', 'show-externals']), cwd=cwd,
+                        extra_env=get_git_extra_env(self.config))
                 # we search for comment lines to strip them out
                 comment_line = re.compile(r"^#.*")
                 ext = ''
@@ -409,7 +438,7 @@ class GitSvnBranch(GitBranch):
         if self.config.sticky_date:
             raise FatalError(_('date based checkout not yet supported\n'))
 
-        cmd = ['git', 'svn', 'clone', self.module]
+        cmd = self.make_git_command(['svn', 'clone', self.module])
         if self.checkoutdir:
             cmd.append(self.checkoutdir)
 
@@ -423,22 +452,22 @@ class GitSvnBranch(GitBranch):
 
         if copydir:
             buildscript.execute(cmd, cwd=copydir,
-                    extra_env=get_git_extra_env())
+                    extra_env=get_git_extra_env(self.config))
         else:
             buildscript.execute(cmd, cwd=self.config.checkoutroot,
-                    extra_env=get_git_extra_env())
+                    extra_env=get_git_extra_env(self.config))
 
         try:
             # is known to fail on some versions
-            cmd = ['git', 'svn', 'show-ignore']
+            cmd = self.make_git_command(['svn', 'show-ignore'])
             s = get_output(cmd, cwd = self.get_checkoutdir(copydir),
-                    extra_env=get_git_extra_env())
+                    extra_env=get_git_extra_env(self.config))
             fd = file(os.path.join(
                         self.get_checkoutdir(copydir), '.git/info/exclude'), 'a')
             fd.write(s)
             fc.close()
             buildscript.execute(cmd, cwd=self.get_checkoutdir(copydir),
-                    extra_env=get_git_extra_env())
+                    extra_env=get_git_extra_env(self.config))
         except:
             pass
 
@@ -455,26 +484,26 @@ class GitSvnBranch(GitBranch):
             quiet = []
 
         cwd = self.get_checkoutdir()
-        git_extra_args = {'cwd': cwd, 'extra_env': get_git_extra_env()}
+        git_extra_args = {'cwd': cwd, 'extra_env': get_git_extra_env(self.config)}
 
-        last_revision = get_output(['git', 'svn', 'find-rev', 'HEAD'],
-                **git_extra_args)
+        last_revision = get_output(self.make_git_command(['svn', 'find-rev', 'HEAD']), 
+               **git_extra_args)
 
         stashed = False
-        if get_output(['git', 'diff'], **git_extra_args):
+        if get_output(self.git_command + ['diff'], **git_extra_args):
             # stash uncommitted changes on the current branch
             stashed = True
-            buildscript.execute(['git', 'stash', 'save', 'jhbuild-stash'],
-                    **git_extra_args)
+            buildscript.execute(self.make_git_command(['stash', 'save', 'jhbuild-stash'],
+                      **git_extra_args))
 
-        buildscript.execute(['git', 'checkout'] + quiet + ['master'],
+        buildscript.execute(self.make_git_command(['checkout'] + quiet + ['master']),
                 **git_extra_args)
-        buildscript.execute(['git', 'svn', 'rebase'], **git_extra_args)
+        buildscript.execute(self.make_git_command(['svn', 'rebase']), **git_extra_args)
 
         if stashed:
-            buildscript.execute(['git', 'stash', 'pop'], **git_extra_args)
+            buildscript.execute(self.make_git_command(['stash', 'pop']), **git_extra_args)
 
-        current_revision = get_output(['git', 'svn', 'find-rev', 'HEAD'],
+        current_revision = get_output(self.make_git_command(['svn', 'find-rev', 'HEAD']), 
                 **git_extra_args)
 
         if last_revision != current_revision:
@@ -502,8 +531,8 @@ class GitCvsBranch(GitBranch):
 
     def _checkout(self, buildscript, copydir=None):
 
-        cmd = ['git', 'cvsimport', '-r', 'cvs', '-p', 'b,HEAD',
-               '-k', '-m', '-a', '-v', '-d', self.repository.cvsroot, '-C']
+        cmd = self.make_git_command(['cvsimport', '-r', 'cvs', '-p', 'b,HEAD',
+               '-k', '-m', '-a', '-v', '-d', self.repository.cvsroot, '-C'])
 
         if self.checkoutdir:
             cmd.append(self.checkoutdir)
@@ -513,29 +542,29 @@ class GitCvsBranch(GitBranch):
         cmd.append(self.module)
 
         if copydir:
-            buildscript.execute(cmd, cwd=copydir, extra_env=get_git_extra_env())
+            buildscript.execute(cmd, cwd=copydir, extra_env=get_git_extra_env(self.config))
         else:
             buildscript.execute(cmd, cwd=self.config.checkoutroot,
-                    extra_env=get_git_extra_env())
+                    extra_env=get_git_extra_env(self.config))
 
     def _update(self, buildscript, copydir=None):
         if self.config.sticky_date:
             raise FatalError(_('date based checkout not yet supported\n'))
 
         cwd = self.get_checkoutdir()
-        git_extra_args = {'cwd': cwd, 'extra_env': get_git_extra_env()}
+        git_extra_args = {'cwd': cwd, 'extra_env': get_git_extra_env(self.config)}
 
         stashed = False
         # stash uncommitted changes on the current branch
-        if get_output(['git', 'diff'], **git_extra_args):
+        if get_output(self.git_command + ['diff'], **git_extra_args):
             # stash uncommitted changes on the current branch
             stashed = True
-            buildscript.execute(['git', 'stash', 'save', 'jhbuild-stash'],
+            buildscript.execute(self.make_git_command(['stash', 'save', 'jhbuild-stash']), 
                     **git_extra_args)
 
         self._checkout(buildscript, copydir=copydir)
 
         if stashed:
-            buildscript.execute(['git', 'stash', 'pop'], **git_extra_args)
+            buildscript.execute(self.make_git_command(['stash', 'pop']), **git_extra_args)
 
 register_repo_type('git', GitRepository)
