Encontrei o mesmo problema em um site hospedado em um pacote de hospedagem compartilhada HostNine. Eles também fornecem ssh
acesso a você , mas infelizmente não têm git
instalado e nem permitem a execução gcc
, dificultando o download e a instalação do git para o usuário.
A única maneira de pensar em solucionar essas restrições foi copiar os binários do git de outro computador que os possuía. Talvez a mesma solução funcione para você e seu host compartilhado do GoDaddy. Aqui está o que eu fiz:
Primeiro, descubra qual arquitetura seu servidor possui. No meu caso, era de 32 bits (i386). Aqui estão algumas maneiras de descobrir isso:
# 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
Em seguida, você precisa encontrar outro computador executando o Linux com a mesma arquitetura e com o git instalado. Eles nem precisam estar executando a mesma distribuição ou versão do Linux, contanto que tenham a mesma arquitetura e você possa encontrar os binários e os arquivos de biblioteca necessários.
Para encontrar a localização do binário principal do git:
> which git
/usr/local/bin/git
Alguns outros binários importantes (como git-receive-pack
) também residem no mesmo diretório, por isso recomendo apenas copiar tudo /usr/local/bin/git*
para garantir que você obtenha tudo o que precisa.
Outros arquivos importantes são dos quais o git depende estão em um diretório 'libexec' em algum lugar no sistema de origem. Se você não copiar esses itens, poderá receber uma mensagem de erro surpreendente ao tentar fazer um git push
, como eu fiz:
git: 'index-pack' is not a git-command. See 'git --help'.
Para localizar o diretório que contém as principais bibliotecas git em target_host, você pode usar este:
> git --exec-path
/usr/local/libexec/git-core
Eu recomendaria copiar esses arquivos primeiro e depois tentar executar o git para ver se ele reclama de alguma biblioteca compartilhada ausente. Caso contrário, você (presumivelmente) está pronto para ir. Se isso acontecer, continue lendo. (Não é necessário copiar em bibliotecas compartilhadas se elas já existirem no host de destino e estiverem na versão correta.)
Você pode copiar os arquivos com scp
, rsync
, ftp
, ou o que você está confortável. Eu usei scp
algo assim:
> 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
Então ssh para target_host. Você precisará adicionar algumas linhas como estas ao seu ~/.bashrc
:
export PATH=$PATH:~/bin
export LD_LIBRARY_PATH=~/lib
export GIT_EXEC_PATH=~/libexec/git-core
Se você esquecer esta etapa, poderá se surpreender ao ver esse erro ao fazer um git push
:
git-receive-pack: command not found
Isso está documentado nas perguntas frequentes do Git em git.or.cz:
Basicamente, o problema é que 'git-receive-pack' não está no $ PATH padrão na extremidade remota.
...
- Verifique se o caminho correto está configurado
.bashrc
(não apenas .bash_profile
)
GIT_EXEC_PATH
está documentado em 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.
Procure seu novo ~/.bashrc
. Agora tente correr git
.
Isto é o que me deu a primeira vez:
> git
git: error while loading shared libraries: libcrypto.so.4: cannot open shared object file: No such file or directory
Consegui descobrir o local das bibliotecas compartilhadas para copiar, executando isso na máquina de origem:
> 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)
No meu caso, eu apenas tive que copiar /lib/libcrypto.so.4
para o ~/lib
meu target_host
e estava tudo bem.
Agora você deve ter um trabalho git
em seu servidor de hospedagem compartilhada e poderá fazê-lo!
Agora você precisa criar um novo repositório git e uma árvore de trabalho em seu servidor ou copiar sua árvore de repositório / trabalho existente.
A propósito, não acho que um repositório vazio seja o que você deseja no servidor nesse caso, pois você disse que queria implantar os arquivos de conteúdo reais (em vez de apenas os config HEAD objects/ refs/
arquivos que seriam incluídos em um repositório vazio) sempre você faz um git push
.
toolmantim.com explica a diferença entre um repositório git regular e um repositório bare:
Um repositório git padrão pressupõe que você o usará como seu diretório de trabalho; portanto, o git armazena os arquivos reais do repositório vazio em um diretório .git ao lado de todos os arquivos do projeto. Repositórios remotos não precisam de cópias dos arquivos no sistema de arquivos, ao contrário das cópias de trabalho, tudo o que precisam são os deltas e os binários do próprio repositório. Isto é o que “nu” significa dar nojo. Apenas o próprio repositório.
Presumirei no momento que você já criou um diretório no seu target_host
local em que deseja implantar seu site (ou o que quer que esteja implantando). Vamos chamar esse diretório ~/www/my_site
. Você pode até enviar ftp sobre todos os seus arquivos para ~/www/my_site already
. (Se você possui ou não não é importante.) Também assumirei por um momento que você ainda não copiou o subdiretório .git para ~/www/my_site
(ele deve funcionar muito bem se você tiver).
Como ainda não existe um repositório git inicializado em target_host, sua primeira etapa seria criar um:
> cd ~/www/my_site
> git init
Então, de qualquer host que tenha o repositório com as alterações mais recentes que você deseja implantar (sua caixa de desenvolvimento, eu acho), basta fazer algo assim para implantar:
> git push --all ssh://username@target_host:port/~/www/my_site/.git
Você pode target_host
receber um aviso como esse se o seu repositório ainda não estiver atualizado:
> 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'.
(Em git
uso normal , você nunca vê essa mensagem, eu acho, porque você normalmente está empurrando para repositórios vazios . Mas, como nosso repositório remoto, nesse caso, é um repositório normal com uma árvore de trabalho e um índice, git
está compreensivelmente preocupado que possa estragar alguma coisa.)
Porém, acho que é seguro configurá-lo para 'ignorar' no seu servidor, porque é provável que você não faça nenhum commit diretamente no repositório lá. (Todas as confirmações provavelmente devem se originar no seu repositório de desenvolvimento e depois serem enviadas ao servidor.)
Então vá em frente e defina isso para que você não veja o aviso toda vez que pressionar:
> ssh target_host 'cd ~/www/my_site/; git config receive.denyCurrentBranch ignore'
O push
próprio atualiza apenas o índice, no entanto, NÃO os arquivos na própria árvore de trabalho. A atualização desses arquivos é apenas uma parte do que estamos tentando fazer, portanto, nosso trabalho não será concluído até que solicitemos git
que o conteúdo do índice seja gravado na própria árvore de trabalho, da seguinte forma:
> ssh target_host 'cd ~/www/my_site/; git reset --hard'
(Nota: Quaisquer alterações que você possa ter tido na sua árvore de trabalho no servidor serão substituídas pelo conteúdo do repositório.)
Também segui a sugestão de mattikus e criei um controle remoto para o meu servidor:
> git remote add h9 ssh://username@target_host:port/~/www/my_site/.git
Então agora tudo o que preciso fazer para implantar é:
> git push --all --force h9
> ssh remote_host 'cd ~/www/my_site/; git reset --hard'
Até cheguei ao ponto de lançar esses comandos em um script que eu nomeei script/deploy
, sempre que eu quiser implantar, só tenho um único comando para executar.
Informe-me se encontrar algum erro nestas instruções ou se souber de uma solução melhor.