Setting up a git repo on the GoDaddy hosting plan

gitgodaddy

I have a project which is version-controlled using git.

What I want to be able to do is set up a repo on my (ssh-enabled) GoDaddy shared hosting package so that I can deploy with a push rather than dragging and dropping in FTP.

Any tips would be appreciated. Best would be an account from someone who's already done it, but I couldn't personally find any online.

Best Answer

I ran into the same problem with a site that I had hosted on a HostNine shared hosting package. They too give you ssh access, but they unfortunately don't have git installed and don't even give you access to run gcc, making it rather difficult to download and install git for your user.

The only way I could think of to work around these restrictions was to copy over the git binaries over from another computer that had them. Perhaps the same solution would work for you and your GoDaddy shared host. Here's what I did:


First figure out what architecture your server has. In my case it was 32-bit (i386). Here are a couple of ways to figure that out:

# uname -a
Linux ___.myserverhosts.com 2.6.18-128.1.6.el5PAE #1 SMP Wed Apr 1 10:02:22 EDT 2009 i686 i686 i386 GNU/Linux

# file /bin/echo
/bin/echo: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped

Next you need to find another computer running Linux with the same architecture and with git installed on it. They don't even have to be running the same distribution or version of Linux, as long as they're the same architecture and you can find the binaries and library files you need.

To find the location of the main git binary:

> which git
/usr/local/bin/git

Some other important binaries (like git-receive-pack) also reside in the same directory, so I recommend just copying over all of /usr/local/bin/git* to make sure you get everything you need.


Other important files are that git depends on are under a 'libexec' directory somewhere on the source system. If you don't copy these over, you may get a surprising error message when you try to do a git push, like I did:

git: 'index-pack' is not a git-command. See 'git --help'.

To find the directory containing the core git libraries on target_host, you can use this:

> git --exec-path
/usr/local/libexec/git-core

I would recommend copying those files over first and then trying to run git to see if it complains about any missing shared libraries. If it doesn't, then you are (presumably) good to go. If it does, then keep reading. (No use copying over shared libraries if they already exist on the target host and are the correct version.)

You can copy the files with scp, rsync, ftp, or whatever you are comfortable with. I used scp, something like this:

> ssh target_host 'mkdir -p ~/bin ~/libexec'
> scp /usr/local/bin/git* target_host:~/bin
> scp -r /usr/local/libexec/git-core target_host:~/libexec

Then ssh to target_host. You will need to add some lines like these to your ~/.bashrc:

export PATH=$PATH:~/bin
export LD_LIBRARY_PATH=~/lib
export GIT_EXEC_PATH=~/libexec/git-core

If you forget this step, you may be surprised to see this error when you do a git push:

git-receive-pack: command not found

This is documented on the Git FAQ on git.or.cz:

Basically the problem is that 'git-receive-pack' is not in the default $PATH on the remote end.

...

  • Making sure you have the correct path set up in .bashrc (not only .bash_profile)

GIT_EXEC_PATH is documented on man git:

   --exec-path
       Path to wherever your core git programs are installed. 
       This can also be controlled by setting the GIT_EXEC_PATH
       environment variable. If no path is given, git will print
       the current setting and then exit.

Source your new ~/.bashrc. Now try running git.


This is what it gave me the first time:

> git
git: error while loading shared libraries: libcrypto.so.4: cannot open shared object file: No such file or directory

I was able to figure out the location of the shared libraries to copy over by running this on the source machine:

> ldd /usr/local/bin/git
libz.so.1 => /usr/lib/libz.so.1 (0xb7fcf000)
libcrypto.so.4 => /lib/libcrypto.so.4 (0xb7ee4000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0xb7ed2000)
libc.so.6 => /lib/tls/libc.so.6 (0xb7da6000)
libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2 (0xb7d92000)
libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0xb7d2d000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0xb7d2a000)
libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0xb7d08000)
libresolv.so.2 => /lib/libresolv.so.2 (0xb7cf5000)
libdl.so.2 => /lib/libdl.so.2 (0xb7cf1000)
/lib/ld-linux.so.2 (0xb7fe8000)

In my case I just had to copy /lib/libcrypto.so.4 over to ~/lib on my target_host and everything was fine.


Now you should have a working git on your shared hosting server and you should be able to push to it!

Now you need to either create a new git repository and work tree on your server or copy your existing repository/work tree over.


By the way, I don't think a bare repository is what you want on the server in this case since you said you wanted to deploy the actual content files (as opposed to just the config HEAD objects/ refs/ files that would be included in a bare repository) whenever you do a git push.

toolmantim.com explains the difference between a regular git repository and a bare repository:

A default git repository assumes that you’ll be using it as your working directory, so git stores the actual bare repository files in a .git directory alongside all the project files. Remote repositories don’t need copies of the files on the filesystem unlike working copies, all they need are the deltas and binary what-nots of the repository itself. This is what “bare” means to git. Just the repository itself.


I will assume for the moment that you have already created a directory on your target_host where you want to deploy your web site (or whatever you're deploying). Let's call that directory ~/www/my_site. You may have even ftp'd over all of your files to ~/www/my_site already. (Whether or not you have is not important.) I'll also assume for the moment that you didn't already copy the .git subdirectory over to ~/www/my_site (it should work just fine if you have though).

Since there's not already a git repository initialized on target_host, your first step would be to create one:

> cd ~/www/my_site
> git init

Then from whichever host has the repository with the latest changes you want to deploy (your development box, I would guess), you just have to do something like this to deploy:

> git push --all ssh://username@target_host:port/~/www/my_site/.git

You may see a warning like this if your repository on target_host isn't already up-to-date:

> warning: updating the current branch
> warning: Updating the currently checked out branch may cause confusion,
> warning: as the index and work tree do not reflect changes that are in HEAD.
> warning: As a result, you may see the changes you just pushed into it
> warning: reverted when you run 'git diff' over there, and you may want
> warning: to run 'git reset --hard' before starting to work to recover.
> warning: 
> warning: You can set 'receive.denyCurrentBranch' configuration variable to
> warning: 'refuse' in the remote repository to forbid pushing into its
> warning: current branch.
> warning: To allow pushing into the current branch, you can set it to 'ignore';
> warning: but this is not recommended unless you arranged to update its work
> warning: tree to match what you pushed in some other way.
> warning: 
> warning: To squelch this message, you can set it to 'warn'.
> warning: 
> warning: Note that the default will change in a future version of git
> warning: to refuse updating the current branch unless you have the
> warning: configuration variable set to either 'ignore' or 'warn'.

(In normal git usage you never see that message, I think, because you're normally pushing to bare repositories. But since our remote repository in this case is a normal repo with both a work tree and an index, git is understandably concerned that it might mess something up.)

I think it's safe for us to set it to 'ignore' on your server, though, because you're not likely to be making any commits directly to the repository there. (All commits should probably originate in your development repository and then be pushed to the server.)

So go ahead and set this so you won't see the warning every time you push:

> ssh target_host 'cd ~/www/my_site/; git config receive.denyCurrentBranch ignore'

The push itself only updates the index, however, NOT the files in the work tree itself. Updating those files is only kind of the entire point of what we're trying to do, though, so our job isn't done until we tell git to write out the contents of the index to the work tree itself, like so:

> ssh target_host 'cd ~/www/my_site/; git reset --hard'

(Note: Any changes you may have had in your work tree on the server will be overwritten by what's in the repository.)

I also followed mattikus's suggestion and created a remote for my server:

> git remote add h9 ssh://username@target_host:port/~/www/my_site/.git

So now all I have to do to deploy is:

> git push --all --force h9
> ssh remote_host 'cd ~/www/my_site/; git reset --hard'

I even went so far as to throw these commands in a script I named script/deploy so any time I want to deploy I just have a single command to run.

Please let me know if you find any mistakes in these instructions or if you know of a better solution.

Related Topic