Setting up a Git Server on Windows Server 2008 R2 (using msysgit and WinSSHD) [Update]

This is a follow-up post from this one. It is inspired by a comment from Dan Kendall. So thanks Dan.

In the portable version of msysgit the git-upload-pack.exe and the git-receive-pack.exe files are also located in the bin/ folder. This allows us to shrink the configuration down and even skip all configuration steps on the client.

The basic setup is the same as in the original post.

The server configuration is a bit different though.

1. Download the portable version of msysgit and extract it to C:\Git.

2. Add C:\Git\bin to the PATH variable.
(If you don’t want to use the portable msysgit for whatever reason, you also have to add C:\Git\libexec\git-core to the PATH)

3. Create a new file in C:\Git\bin and just insert


Save it as shell script (.sh). E.g. “”.
This basically executes the all parameters that are passed and solves the quotes-problem that is mentioned in the original post. There are surely other approaches to solve this issue and if you find a better one please do not hesitate to post a comment.

4. In WinSSHD open the advanced settings and edit the user account(s) you have set up before. Scroll down a bit and uncheck “Use group default exec request prefix”. Then change the “Exec request prefix” to

cmd.exe /c sh 

Be sure to add a space at the end.

5. Done. You can connect to the server with your Git client.

git clone|push|pull|etc. ssh://username@server/path/to/myrepo 

Setting up a Git Server on Windows Server 2008 R2 (using msysgit and WinSSHD)

My first attempt to use a remote Git repository on my Windows Server was to set up a WebDAV site and connect it as network drive on my PC. In principle this works well and the setup is quite fast and easy. The only problem was that it was really slow on my Win 7 machine. Unworkable slow. Even with this magic Auto-detect proxy settings turned off it didn’t improve very much. On Win XP it worked quite well though.
So that was the one of the main reasons why I decided to set up a Git remote repo over SSH. Unfortunately there were some hurdles to take to get this to work.

Basic Setup:

1. Go download and install WinSSHD on your Server. There’s a free version for personal use.

2. Configure WinSSHD. Set up the account(s) you want to use etc. This should be pretty straightforward, as it’s all self-explaining.

3. Now you should be able to connect from a remote client using simple password authentication. For example in Git Bash you can try to connect by typing

ssh username@server

If the connection works. Type ‘exit’ to disconnect and return to the bash

4. Since we don’t want to use password auth the next step is to generate a ssh key pair.
(You can configure the allowed auth types for users/groups in the advanced settings of WinSSHD)

$ ssh-keygen -t rsa -C "Comment" Generating public/private rsa key pair. Enter file in which to save the key (/c/Users/shoehle/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /c/Users/shoehle/.ssh/id_rsa. Your public key has been saved in /c/Users/shoehle/.ssh/ The key fingerprint is:c5:ed:1b:d1:40:94:5b:a1:6b:d1:76:a1:46:8b:7b:fc Comment

The -t specifies the type. In this case RSA with a default length of 2048 bit.
And with the -C parameter you can add a comment.
The default file path should be fine so just press enter at the first prompt.
Then choose a good passphrase for your key.

5. Import the public key ( in WinSSHD to the user account you want to connect with

6. At this point you should be able to connect to your SSH server with the key. If you type ‘ssh username@server’ again you should be able to connect with the key + passphrase.

Ok so these are the basic steps to connect with git to your sever through SSH.
Also if you don’t want to re-enter the passphrase everytime you connect, have a look at this help article from Github

If you now try to clone/push/pull/etc. from the server you will very likely get some errors.
Something like “git-upload-pack: command not found” or “myrepo.git does not appear to be a git repository” or similar.
To fix the first error you can specify the path to the upload/receive pack on the server with some additional parameters. But more on this later.
The second error is due to the command that msysgit tries to execute on the shell. It has single quotes instead of double(or no) quotes that enclose the path to the repository and therefore Windows can’t execute it properly and throws an error. To fix this we use sh.exe from msys.

[Update 05.08.2011]: Here’s a follow-up post that shows an easier way to set up the server. So you can skip the below sections.

Making Git work on the server:

1. If not already done, install msysgit on your server (I would recommend to install it directly to C:\Git or at least a path that has no spaces because I had some weird issues with “spaced” paths)

2. Add C:\Git\bin to the PATH variable. This is very important!! sh.exe and other dependencies are in this folder

3. Now go to C:\Git\bin and add the following two files

4. Open in your favorite editor and insert

C:/Git/libexec/git-core/git-upload-pack.exe $*

5. Open and insert

C:/Git/libexec/git-core/git-receive-pack.exe $*

The $* essentially rips off the single quotes from the repository path argument, so a path that has spaces in it won’t work here either I guess

Basically we’re done now and all git operations from the client should work.
For a clone you have to type

git clone -u 'sh' ssh://username@server/path/to/myrepo.git

or a push would be

git push --exec 'sh' ssh://username@server/path/to/myrepo.git

but that is not very elegant.

Cleaning things up:

1. At first we want to get rid of the whole repo path by specifying a remote alias

git remote add origin ssh://username@server/path/to/myrepo.git

Where “origin” would be the alias name

2. Next we set the config for the git-upload-pack and git-receive-pack so we don’t have to reference the shell script all the time.

git config remote.origin.uploadpack 'sh'


git config remote.origin.receivepack 'sh'

That’s it. Now we can use the normal git commands without any additional parameters:

git clone origin git push origin master git pull origin ...


Alternatively I could have gone with Cygwin + OpenSSH of course and there are some tutorials out there on how to set this up, but I don’t want to have the unnecessary Cygwin bloat on the server unless I really need to. Also these Cygwin tutorials seemed to be much longer than the approach I took.

%d bloggers like this: