Over the weekend I went searching for a way to host remote git repositories on my Dreamhost (DH) account. I do a fair bit of development year round and up to this point have been hosting all my code on my DH account using Subverision. Over the past few weeks I’ve been making the move from Subversion to Git on my local dev machines, and figured it was time to start hosting my git repositories remotely as well.
It took a lot of searching around online and some tinkering, but I was able to get everything setup properly and in the hopes of saving everyone else some time, I’ll post my results here.
First, if you take a look at the DH wiki entry for Git, you will see the very first method described is to run Git on your DH account using WebDAV. If you’re like me, thinking about doing Git over WebDAV probably just left you scratching your head. I think the reason why this is advocated, is because of the way DH setups SSH accounts. By doing git over SSH to a DH account, only one person would be able to remotely push changes, which is fine for my needs. But, if you need to give multiple users access for pushes, then WebDAV would technically work for you. But, I opted not to go down this route.
I chose to simply compile Git locally into my DH account and connect to it over SSH. This blog post on Autopragmatic.com got me about 90% of the way toward completion, so the next few steps are taken directly from his post.
Updated April 21, 2010
Step 1. Compile and Install Git on Dreamhost - This step is not really needed since Dreamhost now has Git version 1.7
The first thing that needs to be done is to compile Git locally into your DH account. I personally have a ~/src directory where I download and compile all my code and I have a ~/packages directory where I install my binaries. You may have a different setup so if so, just substitute those paths accordingly. Also, make sure to substitute $USER with your DH username. (Also note the current stable version of git might be different from what you see here. At the time of this writing, 1.5.4.rc4 was the most recent version, but feel free to install a newer version if available.)
$ cd ~/src$ wget http://www.kernel.org/pub/software/scm/git/git-1.5.4.rc4.tar.gz$ tar xvzf git-1.5.4.rc4.tar.gz$ cd git-1.5.4.rc4$ ./configure --prefix=/home/$USER/packages NO_CURL=1 NO_MMAP=1$ make$ make install$ git --version
There are a few things to be aware of. First, the NO_MMAP=1 parameter is necessary to keep the DH process police from killing your Git process. Git normally creates two 250MB memory map files, and DH will kill your Git process since it sees it consuming over 500MB of memory. I also used the NO_CURL=1 parameter as I will not be needing my git repositories to have the ability to pull from other remote locations. If you do need this functionality, then you will also need to download, compile and install libcurl, but that is beyond the scope of this post. Also, make sure that you have the path of your installed binaries in your $PATH or that last command of git –version will fail. In my case, I have added /home/$USER/packages/bin to my $PATH in my ~/.bashrc file.
Step 2. Create a new bare Git repository
Now that you have installed git, you can start making new repositories. You can, of course, store these repositories anywhere you want. I chose to create a whole new sub-domain under the Dreamhost Domains Panel. Some people prefer to instead create a git subdirectory under an existing domain. Any way is fine, the choice is yours. For the rest of this post I’ll simply be refering to git.example.com as the <PATH> of my git repositories. You will change this to your path.
If you plan on making multiple repositories, the easiest thing to do is simply automate the process by adding the following function to your ~/.bashrc file.
newgit(){ if [ -z $1 ]; then echo "usage: $FUNCNAME project-name.git" else gitdir="/home/$USER/$PATH/$1" mkdir $gitdir pushd $gitdir git --bare init git --bare update-server-info chmod a+x hooks/post-update touch git-daemon-export-ok popd fi}This way you can simply login to your DH account and type:
$ newgit my-new-repos.gitand a new bare repository will be created for you in your <PATH>. Or if you prefer to create a new repository from your local box you could even do it over SSH:
$ ssh $USER@$MACHINE.dreamhost.com newgit my-new-repos.gitStep 3. Pull and push to your new repository
Theoretically, you should now be able to pull and push from this bare repository using the following command:
$ git clone ssh://$USER@$MACHINE.dreamhost.com/home/$USER/$PATH/repo-name.git$ git push originHowever, I found this did not work for me and resulted in the following errors:
Initialized empty Git repository in ~/src/newrepo/.git/Bad port ”fatal: no matching remote headfetch-pack from ’ssh://$USER@$MACHINE.dreamhost.com:/home/$USER/$PATH/my-new-repo.git’ failed.The problem is that the new repository is bare and has absolutely no data in it at all. That led me on another search that brought me to this excellent writeup that got me the rest of the way home. What I did was simply changed directories into my local git repository. If you haven’t even started your codebase locally yet, I would recommend going ahead and doing that.
Create a new directory and create or add in your files, then do the following to setup a local git repos:
$ cd /my/code/path$ git init$ git add .$ git commit -m "initial import"That will create a local git repository in your working directory and commit the initial files. Next follow the next set of commands to add your DH repos as a remote and push your initial codebase up to it
### assuming ssh://server/remote.git resolves to an empty, bare git repo### and that we are chdir()'d to the local repository:$ git push --all ssh://$USER@$MACHINE.dreamhost.com/home/$USER/$PATH/my-new-repos.git$ git remote add origin ssh://$USER@$MACHINE.dreamhost.com/home/$USER/$PATH/my-new-repos.git$ git config branch.master.remote origin$ git config branch.master.merge refs/heads/master$ git fetch$ git merge master$ git branch -a* master origin/masterNow you can simply work locally and do a
$ git pushto push to your DH remote. And if you ever need to you can simply execute a
$ git pullto pull down and merge remote changes.
Step 4. Setup GitWeb (optional)
If you want to be able to access your git repositories via a web browser, you need to setup GitWeb. GitWeb ships with the git source code so you already have it available. You just need to copy the GitWeb files into your git repository directory and make them executable.
cd <PATH>;cp ~/src/git-1.5.4.rc4/gitweb/git* .rm gitweb.perlchmod 755 gitweb.cgiIts a good idea to create a configuration file as well
touch gitweb_config.perlvim gitweb_config.perland put this as the
gitweb_config.perl
content:
# where is the git binary?$GIT = "/home/$USER/packages/bin/git";
#where are our git project repositories?
$projectroot = "/home/$USER/git.example.com";
# what do we call our projects in the gitweb UI?
$home_link_str = "My Git Projects"# where are the files we need for gitweb to display?@stylesheets = ("gitweb.css");$logo = "git-logo.png";$favicon = "git-favicon.png";# what do we call this site?$site_name = "My Personal Git Repositories";Then to get it to actually run in the browser you need to tell apache to serve the files up via CGI. Edit your
.htaccess
file with the following info:
Options +ExecCGI
RewriteEngine OnRewriteRule ^$ gitweb.cgiRewriteRule ^([?].*)$ gitweb.cgi$1Now you should be able to access your git repositories from you web browser at http://git.example.com.
I personally went one step further and password protected my repositories. If you don’t want your git repositories exposed to the whole world, you might want to do the same thing. I used simply HTTP authentication by adding the following to the bottom of my
.htaccess
file:
AuthType BasicAuthName "Private Git Repository Access"AuthUserFile /home/$USER/.htpasswdRequire valid-userThis, of course, requires that you have proper
.htpasswd
file setup which is beyond the scope of this tutorial.
