Ho riscontrato lo stesso problema con un sito ospitato su un pacchetto di hosting condiviso HostNine. Anche loro ti danno ssh
accesso, ma purtroppo non si sono git
installati e non ti danno nemmeno l'accesso per l'esecuzione gcc
, rendendo piuttosto difficile scaricare e installare git per il tuo utente.
L'unico modo in cui potevo pensare di aggirare queste restrizioni era copiare i binari git da un altro computer che li aveva. Forse la stessa soluzione funzionerebbe per te e il tuo host condiviso GoDaddy. Ecco cosa ho fatto:
Per prima cosa scopri quale architettura ha il tuo server. Nel mio caso era a 32 bit (i386). Ecco un paio di modi per capirlo:
# 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
Successivamente è necessario trovare un altro computer con Linux con la stessa architettura e con git installato su di esso. Non devono nemmeno eseguire la stessa distribuzione o versione di Linux, purché abbiano la stessa architettura e sia possibile trovare i file binari e i file di libreria necessari.
Per trovare la posizione del file binario git principale:
> which git
/usr/local/bin/git
Alcuni altri binari importanti (come git-receive-pack
) si trovano anche nella stessa directory, quindi ti consiglio di copiarli tutti /usr/local/bin/git*
per assicurarti di ottenere tutto ciò di cui hai bisogno.
Altri file importanti sono che git dipende da una directory 'libexec' da qualche parte sul sistema di origine. Se non li copi, potresti ricevere un messaggio di errore sorprendente quando provi a fare un git push
, come ho fatto io:
git: 'index-pack' is not a git-command. See 'git --help'.
Per trovare la directory contenente le librerie git principali su target_host, puoi usare questo:
> git --exec-path
/usr/local/libexec/git-core
Consiglierei di copiare prima quei file e poi provare a eseguire git per vedere se si lamenta delle librerie condivise mancanti. In caso contrario, allora sei (presumibilmente) bravo ad andare. In tal caso, continua a leggere. (Non serve copiare su librerie condivise se esistono già sull'host di destinazione e sono la versione corretta.)
È possibile copiare i file con scp
, rsync
, ftp
, o qualsiasi altra cosa che hai dimestichezza con. Ho usato scp
qualcosa del genere:
> 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
Quindi ssh su target_host. Dovrai aggiungere alcune righe come queste al tuo ~/.bashrc
:
export PATH=$PATH:~/bin
export LD_LIBRARY_PATH=~/lib
export GIT_EXEC_PATH=~/libexec/git-core
Se dimentichi questo passaggio, potresti essere sorpreso di vedere questo errore quando esegui una git push
:
git-receive-pack: command not found
Questo è documentato nelle FAQ di Git su git.or.cz:
Fondamentalmente il problema è che 'git-receive-pack' non è nel $ PATH predefinito sull'estremità remota.
...
- Assicurati di aver impostato il percorso corretto in
.bashrc
(non solo .bash_profile
)
GIT_EXEC_PATH
è documentato su 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.
Fonte il tuo nuovo ~/.bashrc
. Ora prova a correre git
.
Questo è quello che mi ha dato la prima volta:
> git
git: error while loading shared libraries: libcrypto.so.4: cannot open shared object file: No such file or directory
Sono stato in grado di capire la posizione delle librerie condivise da copiare eseguendo questo sul computer di origine:
> 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)
Nel mio caso ho dovuto copiare /lib/libcrypto.so.4
verso ~/lib
il mio target_host
e tutto è andato bene.
Ora dovresti avere un lavoro git
sul tuo server di hosting condiviso e dovresti essere in grado di spingerlo!
Ora devi creare un nuovo repository git e un albero di lavoro sul tuo server o copiare il tuo repository / albero di lavoro esistente.
A proposito, non penso che un repository nudo sia quello che vuoi sul server in questo caso poiché hai detto che volevi distribuire i file di contenuto effettivi (al contrario dei soli config HEAD objects/ refs/
file che sarebbero inclusi in un repository nudo) ogni volta tu fai un git push
.
toolmantim.com spiega la differenza tra un repository git normale e un repository nudo:
Un repository git predefinito presuppone che lo utilizzerai come directory di lavoro, quindi git archivia i file del repository nudo effettivi in una directory .git insieme a tutti i file di progetto. I repository remoti non hanno bisogno di copie dei file sul filesystem a differenza delle copie funzionanti, tutto ciò di cui hanno bisogno sono i delta e le cose binarie del repository stesso. Questo è ciò che "nudo" significa git. Solo il repository stesso.
Presumo per il momento che tu abbia già creato una directory sul tuo sito in target_host
cui vuoi distribuire il tuo sito web (o qualunque cosa tu stia distribuendo). Chiamiamo quella directory ~/www/my_site
. Potresti anche aver fatto ftp su tutti i tuoi file ~/www/my_site already
. (Che tu abbia o no non è importante.) Per il momento suppongo anche che tu non abbia già copiato la sottodirectory .git ~/www/my_site
(dovrebbe funzionare bene se hai pensato).
Dato che non esiste già un repository git inizializzato su target_host, il primo passo sarebbe quello di crearne uno:
> cd ~/www/my_site
> git init
Quindi da qualsiasi host abbia il repository con le ultime modifiche che vuoi distribuire (la tua casella di sviluppo, immagino), devi solo fare qualcosa del genere per distribuire:
> git push --all ssh://username@target_host:port/~/www/my_site/.git
Potresti visualizzare un avviso come questo se il tuo repository on target_host
non è già aggiornato:
> 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'.
(Nell'uso normale git
non vedi mai quel messaggio, penso, perché normalmente stai spingendo verso i repository nudi . Ma poiché il nostro repository remoto in questo caso è un normale repository con un albero di lavoro e un indice, git
è comprensibilmente preoccupato che potrebbe rovinare qualcosa.)
Penso che sia sicuro per noi impostarlo su "ignora" sul tuo server, perché non è probabile che tu stia facendo alcun commit direttamente sul repository lì. (Tutti i commit dovrebbero probabilmente avere origine nel repository di sviluppo e quindi essere inviati al server.)
Quindi vai avanti e imposta questo in modo da non vedere l'avvertimento ogni volta che premi:
> ssh target_host 'cd ~/www/my_site/; git config receive.denyCurrentBranch ignore'
Lo push
stesso aggiorna solo l'indice, tuttavia, NON i file nell'albero di lavoro stesso. L'aggiornamento di questi file è solo il tipo dell'intero punto di ciò che stiamo cercando di fare, quindi il nostro lavoro non viene svolto fino a quando non diciamo git
di scrivere il contenuto dell'indice nell'albero di lavoro stesso, in questo modo:
> ssh target_host 'cd ~/www/my_site/; git reset --hard'
(Nota: qualsiasi modifica che potresti aver avuto nella tua struttura di lavoro sul server verrà sovrascritta da ciò che è nel repository.)
Ho anche seguito il suggerimento di mattikus e ho creato un telecomando per il mio server:
> git remote add h9 ssh://username@target_host:port/~/www/my_site/.git
Quindi ora tutto ciò che devo fare per distribuire è:
> git push --all --force h9
> ssh remote_host 'cd ~/www/my_site/; git reset --hard'
Sono persino arrivato al punto di lanciare questi comandi in uno script che ho chiamato script/deploy
così ogni volta che voglio distribuire ho solo un singolo comando da eseguire.
Per favore fatemi sapere se trovate errori in queste istruzioni o se conoscete una soluzione migliore.