2009-09-23 8 views
5

Nella produzione, mantengo due siti - beta e release. Ogni punta a una directory diversa tramite un link simbolico (per esempio)come faccio a distribuire più sportelli a diverse directory tramite git push?

beta_public_html -> /home/scott/myapp/trunk/public 
public_html  -> /home/scott/myapp/branches/1.2.3/public 

Sono un lungo tempo svn utente, passare a git. Sono abituato a distribuire tramite svn update e cambiare il soft link su un nuovo ramo, le cose sono piuttosto semplici.

Ora sto muovendo a git. Ho ancora bisogno di avere i due soft link (si tratta di un'applicazione Rails utilizzando passeggeri), anche se ora voglio che puntano a due diversi rami Git ("beta" e "rilascio", dico). E voglio essere in grado di aggiornarli tramite git push (o git pull).

Domanda Parte 1: Non sono sicuro che il modo migliore per fare questo.

Il modo in cui avevo iniziato a fare era di distribuire solo a due diversi telecomandi, per esempio

git push ssh://[email protected]/home/scott/myapp-beta beta 
git push ssh://[email protected]/home/scott/myapp-release release 

Ma questo non funziona perché push non aggiorna l'albero di lavoro per impostazione predefinita.

Quindi vado nelle directory remote ed eseguo git reset --hard la prima volta, e tira l'albero di lavoro. Ma spingo ancora e non riesco a far apparire la nuova spinta - rimane solo all'inizio.

(BTW, nota che non riesco a spingere su "myapp-beta.git" - che non riesce, devo premere sul nome della directory.Mi sono preoccupato che questo è parte del problema, ma io non so cosa ho fatto di sbagliato qui.)

Quindi, se la risposta alla domanda 1 è che il mio metodo va bene, domanda parte 2: cosa c'è di sbagliato in ciò che sto effettivamente facendo? Se ci sono dei ganci che dovrei usare, qualcuno può indicarmi?

(Una risposta alla domanda 1 che dice "eseguito questi sette passaggi manuali" non sarà una risposta terribilmente utile, visto che svn checkout + ln -s sono due passi.)

Grazie. Voglio tornare a scrivere il codice.

+0

non ti piace il controllo del codice sorgente? – knittl

+0

Il controllo del codice sorgente è un mezzo per un fine, non un fine in sé. –

+0

ok, non stavo cercando di iniziare una conversazione sull'amore per il controllo del codice sorgente. Rimozione del commento di throwaway. – scottru

risposta

2

L'articolo Git push is worse than worsless ha un'interessante discussione su un problema simile.

Uno della soluzione e la conclusione comporta:

  • un repository nudo su server di produzione
  • un repository clonato con un gancio per tirare quanto è stato spinto in bare

Quindi nel tuo caso,

  • un unico repository su cui puoi spingere beta e rilasciare i rami
  • due repo clonato "beta" e "rilascio" con un gancio per estrarre i rispettivi rami dal repository nudo.

In breve: un passaggio: git push.Non più link per gestire (dal momento che la directory non rappresentano più una filiale a Git, a differenza di SVN)


Per quanto riguarda la parte gancio, un post-receive hook nel repository nudo potrebbe essere tutto quello che vi serve

Vedi Git Tip: Auto update working tree via post-receive hook

$ cd bare 
$ chmod +x .git/hooks/post-receive 

with a post-receive hook like 

#!/bin/sh 
cd ../../beta 
env -i git reset --hard 
cd ../../release 
env -i git reset --hard 

Nota:

dall'inizio post-receive gancio s con la variabile di ambiente GIT_DIR impostare la cartella repo/.git, quindi non importa quale strada si 'cd' in esso cercherà sempre di eseguire qualsiasi seguenti comandi git lì.
fissaggio questo è semplicemente una questione di disinserimento del GIT_DIR.

'env -i' does just that: ignora completamente l'ambiente ereditato e utilizza solo le variabili ei valori forniti.

+0

Grazie, Von. Leggo l'articolo e capisco la prima soluzione, che in realtà comporta solo un tiro sul lato remoto (più a volte un reset). Lavorerò attraverso questo e vedrò se riesco a capire come funziona. Hai qualche indicazione alle versioni di questi ganci? – scottru

+0

Seconda parte: questo ha funzionato fondamentalmente - ho dovuto cambiare "git reset --hard" con "git pull", ma per il resto va bene. (Bene, questo e pieno percorso per git, solo per i posteri.) Grazie Von! Apprezzo molto l'aiuto. – scottru

0

Io uso un post-receivehook come questo per pubblicare il mio sito Web, perché Git non tocca la directory di lavoro quando si fa un push. Il repository remoto è un repository non nullo, cioè ha una directory di lavoro.

if [ -n $GIT_DIR ]; then 
    # Current dir is "<reporoot>/.git/", but we need to run reset at "<reporoot>/". 
    # Clearing GIT_DIR is needed, or reset will fail with "fatal: Not a git repository: '.'" 
    unset GIT_DIR 
    cd .. 
fi 
git reset --hard 

(BTW, notare che io non riesco a spingere a "myapp-beta.git" -. Che non riesce, devo spingere al nome della directory io sono preoccupato che questo è parte del problema, ma non so che cosa ho fatto di sbagliato qui.)

Durante la creazione di un repository Git nudo (git init --bare) che non ha una directory di lavoro, è una convenzione per assegnare un nome alla directory "something.git". Quando avere un repository non-nuda, il repository è in realtà nella sottodirectory ".git", in modo che il percorso completo è 'qualcosa/.git'. Sembra che in entrambi i casi si possa tralasciare la parte ".git" e Git la rileverà automaticamente.

0

Io non sono davvero differenza delle altre soluzioni, ma penso che ci sia un meno hack'ish "via Git" per fare questo. Ecco quello che vorrei fare:

  1. Sul mio assistente, mi piacerebbe istituire una sorta di un archivio centralizzato (per essere gestito da Gitosis o qualcosa del genere).
  2. Dal lato client, avevo costantemente tirare dal repository, apportare le modifiche e spingere indietro. I rami sono naturalmente, gestiti automaticamente.
  3. mi piacerebbe tirare il ramo richiesta dal Gitosis in public_html/beta_public_html del server. Lo terrei in sincronia con Gitosis periodicamente usando un job Cron. Se non ti piace l'idea di lavoro di Cron, puoi sempre usare una sorta di hook + script come gli altri hanno sottolineato.
+0

In realtà, di solito mantengo il mio repository Git hosting (GitHub) separato dal mio web hosting (SliceHost). – artagnon

1

La soluzione è quella di spingere a singolo repository, che impiegano update o post-receivehook.

Ci sono alcune possibilità separate per creare due checkout, che possono essere utilizzati in hook (sul server).Andando da più leggero:

  • Se non avete bisogno di quei due ne siamo andati directory (controllato le versioni) per essere effettivamente repository git, si può semplicemente utilizzare git-archive per export due istantanee (due rami)

    git archive --format=tar --prefix=public_html/ master | (cd /var/www/html && tar xf -) 
    git archive --format=tar --prefix=beta_public_html/ devel | (cd /var/www/html && tar xf -) 
    

    dove "master" e "devel" sono i nomi dei rami che si desidera verificare. Si noti che --format=tar non è strettamente necessario, poiché il formato tar è predefinito per "git archive". Si potrebbe anche voler rimuovere i vecchi contenuti (" rm -rf public_html/" prima 'tar xf -' in prima linea, uniti con '&&', e allo stesso modo per la seconda linea).

    modo alternativo per l'esportazione di file potrebbe essere quella di utilizzare i comandi di basso livello "git read-tree" (che scrive albero all'indice) e "git checkout-index" (che copia i file da indice per l'area di lavoro).

    In questa soluzione il repository si spinge in può (e dovrebbe) essere nudi, cioè senza directory stessa di lavoro

  • Un'altra soluzione potrebbe essere per il repository inserito per avere due directory di lavoro, che possono essere create utilizzando lo script git-new-workdir da contrib/workdir. Ognuna di quelle aree di lavoro sarebbe una verifica del ramo appropriato di questo repository.

    Poi update o post-receive gancio sarebbe disinserire GIT_DIR, andare in quelle aree di lavoro (public_html e beta_public_html), e fare "git reset --hard" lì.

    In questa soluzione, "checkouts" avrebbe alcuni metainfo relativi a git (nella directory nascosta .git).

  • Un'altra soluzione potrebbe essere quella di avere due (supplementari) repository slave. Spingendo nel repository principale (master), quindi, (tramite hook) si può spingere in questi due repository slave, dove i loro hook farebbero "git reset --hard" o equivalente, o andare in questi due repository slave e fare uno "git pull" dal master lì.

    Questi due repository slave non sono nudi e possono essere [direttamente in] public_html e beta_public_html. In questa soluzione, i "checkouts" sarebbero gli stessi repository git a tutti gli effetti.

    È possibile migliorare questa configurazione facendo in modo che i repository slave abbiano "alternati" (database oggetto alternativo) in modo che puntino al repository principale (ad esempio, clonare con "git clone --shared ..."); senza questo database di oggetti in slave inizia il collegamento diretto al master. Questo è ovviamente possibile solo se master e slave si trovano sullo stesso filesystem.

    Nota questa soluzione consente al repository principale di trovarsi su host diversi rispetto agli archivi slave. (anche se penso che questa sia la flessibilità di cui non hai bisogno).

  • Infine è possibile, invece di configurazione corrente distribuire gitweb o qualche altro git interfaccia web (vedi InterfacesFrontendsAndTools e Gitweb pagine wiki per un elenco parziale), in modo che gli utenti possano navigare versioni diverse e diversi rami del vostro repository a il loro tempo libero

    In gitweb (e credo anche in un'altra interfaccia Web git) grazie al supporto URL path_info è possibile visualizzare i file nel browser e seguire correttamente i collegamenti (se sono locali), vedere ad es. git.html from 'html' branch of git.git repository at repo.or.cz.


P.S. "git push" non aggiorna la directory di lavoro nel repository remoto per impostazione predefinita, perché se qualcuno sta lavorando nel repository non nudo in cui viene inserito, tale push laterale può essere molto inaspettato e portare a una perdita di lavoro.

+0

notando solo per i futuri lettori che si tratta di una scrittura utile - ho finito per seguire la prima risposta a questa domanda, e ho finito per implementare la seconda opzione in questa risposta con il mio script - questa è una grande descrizione delle opzioni. Grazie! – scottru

Problemi correlati