When Git Clone Does Not Work On Mac OSX

Friday, 3 April 2009

by Silumesii Maboshe

I had some trouble with Mac OS X and getting Git clone to work over SSH on my local network last week. In case you might be in a similar situation, here is how I went about solving it.

My Setup

My repository server for this was a Mac Mini running Mac OS X Leopard 10.5.6 and I used MacPorts to install Git.

server$ sudo port install git-core +doc +gitweb +svn +bash_completion

This installed Git version 1.6.2.

I set up a test project on the server in a bare git repository called confabulator. I also have an account reposadmin with permissions to configure Git repositories:

server$ sudo -u reposadmin mkdir -m 770 /path/to/repository/confabulator.git
server$ cd /path/to/repository/confabulator.git
server$ sudo -u reposadmin git --bare init --shared=group

From the development machine, I pushed the working confabulator project in to the new bare Git repository on the server.

dev$ cd confabulator
dev$ git remote add reposserver ssh://server.local/path/to/repository/confabulator.git
dev$ git push reposserver master

All was right with the world and I were beaming from ear to ear.

My Problem

Eager to begin coding, I tried to clone confabulator using SSH and got a strange error.

dev$ git clone ssh://server.local/path/to/repository/confabulator.git
Initialized empty Git repository in /Users/florence/Desktop/confabulator/.git/
bash: git-upload-pack: command not found
fatal: The remote end hung up unexpectedly

Hung up unexpectedly? Hell hath no fury like a repository scorned!

The problem is that on Mac OS X, a non-interactive login does not set up environment variables using the bash profile in ~/.profile.

My .profile on the server includes this:

...
export PATH=/opt/local/bin:/opt/local/sbin:$PATH
...

Since Git, on the server, lives in /opt/local/bin

server$ which git
/opt/local/bin/git

and the correct $PATH does not get loaded, it does not know where to itself and hastily breaks communication because of its identity crisis.

My Solution

In non-interactive mode, you can force login to pick up the correct environment variables.

In my particular case I also learned that a non-interactive login loads ~/.bashrc instead of ~/.profile. As such I created a symbolic link on each server account to .profile called .bashrc. This means that whether in interactive or non-interactive mode, the $PATH variables will now be identical. Notice that this will have to be done for each user.

server$ cd ~
server$ ln -s .profile .bashrc

And all was right with the world again.

dev$ git clone ssh://server.local/path/to/repository/confabulator.git
remote: Counting objects: 527, done.
remote: Compressing objects: 100% (467/467), done.
remote: Total 527 (delta 52), reused 527 (delta 52)
Receiving objects: 100% (527/527), 1.11 MiB | 884 KiB/s, done.
Resolving deltas: 100% (52/52), done.

Hope this was helpful.