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
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
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
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
If you forget this step, you may be surprised to see this error when you do a
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
GIT_EXEC_PATH is documented on
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
This is what it gave me the first time:
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)
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
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: 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: To squelch this message, you can set it to 'warn'.
> 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'.
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'
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.