Come passare a un repository Git non nudo?


150

Di solito lavoro su un server remoto tramite ssh (screen e vim), dove ho un repository Git. A volte non sono online, quindi ho un repository separato (clonato dal mio telecomando) sul mio laptop.

Tuttavia, non riesco a estrarre da questo repository sul lato remoto perché di solito sono protetto da un firewall o non ho un IP pubblico.

Ho letto che dovrei spingere solo in un repository nudo. Come devo quindi inviare le mie modifiche al mio repository remoto?



3
avere 2 repository remoti, uno nudo e uno normale e utilizzare hook. sembra una seccatura, ma secondo git ready e il wiki ufficiale di git , dovresti solo spingere verso un repository nudo . questo è probabilmente il motivo per cui la maggior parte degli host repository git (ad esempio GitHub, Bitbucket) include hook post-ricezione, in modo da poter pubblicare un URL sul proprio server che esegue uno script che viene eseguito ad esempio git pull github master.
Jake Berger,

Risposte:


137

receive.denyCurrentBranch updateInstead

Questa opzione è stata aggiunta in Git 2.3 e consente al server di aggiornare il suo albero di lavoro se è pulito.

Quindi, se ti assicuri di impegnarti sempre prima di estrarre localmente e mantenere un albero di lavoro pulito sul server (cosa che dovresti fare per evitare conflitti di unione), allora questa opzione è una buona soluzione.

Esempio di utilizzo:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

Produzione:

a
b

è possibile spingere senza creare un repository nudo come fa
heroku

2
@ANinJa Non capisco, non è esattamente quello che fa il mio esempio?
Ciro Santilli 28 冠状 病 六四 事件 法轮功

è --localfacoltativo?
Yukulélé,

@ Yukulélé --localinfluenza solo la directory corrente, --globalinfluenza tutti i repository git con ~/.gitconfig, vedi man git-config.
Ciro Santilli 10 冠状 病 六四 事件 法轮功

1
grazie @CiroSantilli 新疆 改造 中心 六四 事件 法轮功 dopo aver letto il documento confermo che non è necessario "(si può dire --local ma che è l'impostazione predefinita)"
Yukulélé l'

146

La migliore opzione

Probabilmente il modo più pulito, meno confuso e più sicuro per spingere nel tuo repository remoto non nudo, è quello di spingere verso i rami dedicati nel telecomando che rappresentano i rami del tuo laptop.

Diamo un'occhiata al caso più semplice e supponiamo che tu abbia un solo ramo in ciascun repository: master. Quando si passa al repository remoto dal proprio laptop, invece di premere master -> master, premere master -> laptop-master (o un nome simile). In questo modo il push non influisce sul ramo master attualmente estratto nel repository remoto. Per fare ciò dal laptop, il comando è piuttosto semplice:

git push origin master:laptop-master

Ciò significa che il ramo master locale verrà trasferito al ramo denominato "laptop-master" nel repository remoto. Nel tuo repository remoto, avrai un nuovo ramo chiamato "laptop-master" che puoi quindi unire nel tuo master remoto quando sei pronto.

Opzione alternativa

È anche possibile semplicemente inviare il comando master -> master, ma in genere non è consigliabile eseguire il push sul ramo attualmente estratto di un repository non bare, perché può essere fonte di confusione se non si capisce cosa sta succedendo. Questo perché il push su un ramo estratto non aggiorna l'albero di lavoro, quindi git statusil check-in nel ramo estratto che è stato inserito mostrerà esattamente le differenze opposte rispetto a quanto è stato spinto più di recente. Sarebbe particolarmente confuso se l'albero di lavoro fosse sporco prima che la spinta fosse fatta, il che è un grande motivo per cui questo non è raccomandato.

Se vuoi provare a premere semplicemente master -> master, il comando è solo:

git push origin

Ma quando torni al repository remoto, molto probabilmente vorrai fare un git reset --hard HEADper sincronizzare l'albero di lavoro con il contenuto che è stato inviato. Questo può essere pericoloso , perché se ci sono cambiamenti non impegnati nell'albero di lavoro remoto che si desidera mantenere, li cancellerà. Assicurati di sapere quali sono le conseguenze di questo prima di provarlo, o almeno prima fai un backup!

EDIT Da Git 2.3, puoi usare git push "push-to-deploy": https://github.com/blog/1957-git-2-3-has-been-released . Ma spingere verso un ramo separato e quindi l'unione è di solito meglio poiché fa un'unione effettiva (quindi funziona con cambiamenti non impegnati proprio come fa l'unione).


1
È possibile automatizzare la ramificazione dopo aver spinto il laptop-master?
rdoubleui,

3
@rdoubleui: intendevi "automatizzare l' unione "? In tal caso, no, non è possibile automatizzare l'unione perché non è possibile garantire la fusione senza l'intervento umano. Potrebbero esserci conflitti che devono essere risolti.
Dan Molding,

7
nelle versioni successive (?), git config receive.denyCurrentBranch ignoredeve essere eseguito prima di passare ai
repository

3
Ottima risposta @DanMoulding, grazie. @rdoubleui: puoi sempre salvare una riga di comando come la seguente come funzione bash:git push origin master:laptop-master && ssh user@remotemachine 'cd repos_path && git merge laptop-master'
Rich

@rdoubleui per automatizzare l'unione, puoi usare gitolite e impostarlo (un po 'complicato) per rendere il non nudo impegnare tutto sporco e spingerlo sulla versione gitolite (nuda) usando il trigger pre-git. Dopodiché se la fusione non può essere risolta nel non nudo, rifiuterà la tua spinta, quindi sai che devi tirare prima, risolvere le fusioni e spingere di nuovo. Non l'ho ancora impostato, ma sto lavorando e penso che possa funzionare.

17

Suggerirei di avere un repository nudo e un repository di lavoro locale (non nudo) nel tuo server. È possibile trasferire le modifiche dal repository nudo al laptop al server e quindi passare da quel repository nudo al repository funzionante sul server. Il motivo per cui dico questo è perché potresti avere molti rami completi / incompleti nel server che vorresti replicare sul laptop.

In questo modo non è necessario preoccuparsi dello stato del ramo verificato sul repository funzionante del server mentre si spingono le modifiche al server.


4

Un'altra opzione è quella di impostare un tunnel SSH inverso in modo da poter tirare invece di spingere.

# start the tunnel from the natted box you wish to pull from (local)
$ ssh -R 1234:localhost:22 user@remote

# on the other box (remote)
$ git remote add other-side ssh://user@localhost:1234/the/repo
$ git pull other-side

E se vuoi che il tunnel venga eseguito in background

$ ssh -fNnR 1234:localhost:22 user@remote

1

Tu puoi fare:

$git config --bool core.bare true

questo può essere fatto nel repository nudo o centrale in modo che accetti tutti i file che vengono inviati da repository non nudi. Se lo fai in un repository non bare, non possiamo inviare alcun file dal repository non bare a nudo.

Se stai praticando GIT creando un repository centrale e non nudo nel PC, potrebbe non mostrare i file inviati in alcuni PC, ma è stato inviato. puoi verificarlo eseguendo.

$git log in repo centrale.

A parte che se passi a GitHub mostrerà i file lì.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.