Utilizzo di Git su più sistemi senza accesso alla rete


84

Voglio usare il controllo della versione ma, per motivi di sicurezza, il server su cui sto lavorando non ha accesso a Internet: posso solo spostare i file su un'unità flash USB. Posso ancora usare Git con questa configurazione? Posso creare piccole patch che posso applicare su un repository Git?


65
Il tuo titolo non dice accesso alla rete, la tua domanda non dice accesso a Internet; un'enorme differenza.
tkausl,

7
@TutuKaeen Puoi avere una rete locale che non è connessa a Internet. Quindi, invece di github.com, devi configurare git server su es. 192.168.1.100 e tutto il resto funziona allo stesso modo.
Agent_L

12
@TutuKaeen: la domanda fondamentale è se è possibile la comunicazione di rete diretta (o indiretta) tra le due macchine. Quindi, nel tuo caso, entrambe le macchine sono collegate in rete, ma le reti sono separate? In tal caso, modifica tali informazioni nella tua domanda.
sleske,

15
@TutuKaeen La tua domanda non è chiara. Dici di voler utilizzare il controllo versione, ma nei tuoi commenti hai bisogno che ti aiuti a distribuire in produzione. Questi problemi non si sovrappongono sempre. Penso che tu abbia buone risposte di seguito ora, ma in futuro sarebbe utile se la tua domanda fosse più completa sulle tue esigenze, che sembrano essere: "Voglio usare il controllo della versione, la mia macchina di sviluppo non ha accesso a Internet, ha accesso alla rete ma non alla macchina di produzione e voglio sapere come ottenere il codice dal controllo della versione sulla macchina di produzione. "
DavidS

4
Sembra strano usare il termine serverper una macchina non connessa a nessuna rete. Potrebbe essere solo una rete locale anche senza accesso a Internet, ma è comunque una rete.
Patrick Gregorio,

Risposte:


157

Certo, non c'è nulla in Git che richiede un protocollo particolare. Appena pronto, il client standard supporta HTTP (S), SSH, il protocollo Git personalizzato e, soprattutto, il protocollo locale . Questo richiede solo un percorso verso una .gitdirectory locale , che può trovarsi all'interno della directory di lavoro ( /path/to/project/.git) o solo una directory vuota ( /path/to/project.git), sebbene la denominazione sia solo una convenzione.

Ciò significa che puoi, ovviamente, aggiungere un'unità flash come telecomando:

git remote add origin /mnt/flashdrive/foo.git

o, su Windows:

git remote add origin F:\foo.git

O anche aggiungerlo come telecomando aggiuntivo con un nome diverso (se preferisci originpuntare verso un server Internet da qualche parte):

git remote add flashdrive /mnt/flashdrive/foo.git

Quindi puoi semplicemente premere / tirare su / da questo telecomando come un altro.

Se leggi la documentazione , noterai che esiste anche un file://protocollo che si comporta in modo leggermente diverso. Si consiglia di utilizzare un percorso locale che utilizzerà alcune ottimizzazioni aggiuntive: se si utilizza il file://protocollo, git utilizzerà alcuni componenti di rete standard (per comunicare con il disco locale), che è più lento.


50
Per aggiungere a questa risposta eccezionale, potrebbe anche valere la pena investigare utilizzando un repository "nudo" sull'unità flash. i repository "nudi" non hanno un albero funzionante, quindi eliminano una categoria di potenziali problemi se usati come "punti di autorità" condivisi, che sembrano casi d'uso dell'OP.
Iron Gremlin,

5
L' file://è anche un po 'più flessibile. Ti consente di utilizzare alcune funzionalità (come i cloni superficiali) che non puoi utilizzare con un percorso locale.
Austin Hemmelgarn,

1
@IronGremlin Potresti approfondire questa nozione di "punto di autorità condiviso"? Non sono un esperto di Git e sono curioso di sapere cosa intendi con questo.
Razze di leggerezza in orbita,

2
@LightnessRacesinOrbit - Questo è un argomento piuttosto denso, ma, fondamentalmente, git è distribuito, quindi ognuno ha la propria storia. A può chiedere a B la sua versione della storia, ma C non lo sa a meno che qualcuno non glielo dica. Avere un unico repository per archiviare la storia "autorevole" significa che D funge da stanza di compensazione per le storie. Quindi, A dice a D dei cambiamenti, e B e C sanno parlare con D per rimanere aggiornati, piuttosto che fare cose del canale laterale tra di loro. Nel caso specifico, se il server OP è C e l'unità flash è D, si assicura che il server non venga escluso dalle interazioni A / B.
Iron Gremlin,

6
@LightnessRacesinOrbit Importante notare qui che nudo non deve significare autorevole, è solo utile in quel contesto. Ad esempio, è utile anche perché, in mancanza di un albero di lavoro, è un footprint di spazio su disco minore (o larghezza di banda). Questo era molto più importante di quanto non sia ora, ma continua a emergere.
Iron Gremlin,

46

Su un singolo computer, non è necessario nulla di speciale. Esegui git initnella directory desiderata e lavora con Git come faresti normalmente.

Per sincronizzare un repository su più computer, esistono diversi metodi.

Metodo 1a (nessuna rete): è possibile creare un "repository nudo" sulla chiavetta USB, quindi spingere verso di esso e estrarre da esso come si farebbe con qualsiasi altro repository remoto. In altre parole, le operazioni di repository tramite percorsi locali non sono diverse dalle operazioni tramite URL SSH o HTTPS.

  1. Creare un repository "remoto":

    $ git init --bare /mnt/Stick/Repositories/Large_Project.git
    
  2. Nel computer 1, spingi tutto su di esso:

    $ cd ~/Large_Project
    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git push usb master
    
  3. Nel computer 2, bene, come sempre.

    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git pull usb
    

(Puoi anche spingere / recuperare / estrarre direttamente da un URL o percorso).

Metodo 1b (rete interna): se si dispone di un server interno con SSH disponibile e se è installato Git, è possibile fare come sopra , semplicemente specificare un indirizzo SSH usando la sintassi [user@]host:patho ssh://[user@]host/path.

  1. Creare un repository "remoto" eseguendolo git init --bare <somepath.git>sul server designato (tramite SSH).

  2. Nel computer 1, come mostrato in precedenza.

    $ git remote add origin myserver.example.com:Gits/Large_Project.git
    

    O se preferisci:

    $ git remote add origin ssh://myserver.example.com/Gits/Large_Project.git
    
  3. Nel computer 2, di nuovo uguale al metodo 1a.


Metodo 2: è possibile creare "bundle di trasferimento" che archiviano un determinato elenco di commit in un singolo file.

Sfortunatamente i comandi bundle non ricordano automaticamente ciò che è stato già raggruppato l'ultima volta, quindi è necessario taggare manualmente o tenere nota. Prenderò solo gli esempi dal manuale di git-bundle.

  1. Nel computer 1, crea un pacchetto dell'intero ramo:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle master
    $ git tag -f last-bundled master
    
  2. Nel computer 2, estrarre dal bundle come se fosse un repository:

    $ cd ~/Large_Project
    $ git pull /mnt/Stick/Project.bundle
    

I bundle successivi non devono impacchettare il tutto master- possono invece impacchettare solo i commit appena aggiunti last-bundled..master.

  1. Nel computer 1, crea un pacchetto di commit appena aggiunti:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle last-bundled..master
    $ git tag -f last-bundled master
    
  2. Come sopra.


in realtà non sarebbe male per i miei scopi, anche in effetti nulla è "primario" in quanto ogni repository ha tutta la storia, quindi puoi ricrearlo ogni volta che qualcosa va male
Tutu Kaeen

manual tagging or note-keeping is needed, un'opzione a meno che il repository non sia molto grande è git bundle create my.bundle --all
:,

Mi piace di più questa risposta in quanto è più illustrativa anche se la risposta accettata e questo dice la stessa cosa.
Rystraum,

Qual è il significato dell'opzione "nuda"?
Razze di leggerezza in orbita

1
Crea un repository che è solo il database (quello che normalmente si trova nella .git/cartella nascosta), senza un "albero di lavoro" (i file modificabili). È la forma preferita per i repository a cui sei interessato git push.
Grawity

20

git bundle create

Uno dei metodi consiste nell'utilizzare l'archiviazione esterna per scambiare dati tra repository è il bundle git . In questo modo hai solo file singoli per ogni trasferimento, non repository Git intermedi.

Ogni "git push" si trasforma in creazione di un file, "git fetch" recupera le cose da quel file.

Sessione demo

Creare il primo repository e fare il primo "push"

gitbundletest$ mkdir repo1

gitbundletest$ cd repo1

repo1$ git init
Initialized empty Git repository in /tmp/gitbundletest/repo1/.git/
repo1$ echo 1 > 1 && git add 1 && git commit -m 1
[master (root-commit) c8b9ff9] 1
 1 file changed, 1 insertion(+)
 create mode 100644 1

repo1$ git bundle create /tmp/1.bundle master HEAD
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 384 bytes | 384.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)

"clonazione" nel secondo repository (ovvero il secondo computer):

gitbundletest$ git clone /tmp/1.bundle repo2
Cloning into 'repo2'...
Receiving objects: 100% (3/3), done.

gitbundletest$ cd repo2/

repo2$ cat 1
1

Apportare alcune modifiche e "trasferirle" in un altro file bundle:

repo2$ echo 2 > 1 && git add 1 && git commit -m 2
[master 250d387] 2
 1 file changed, 1 insertion(+), 1 deletion(-)

repo2$ git bundle create /tmp/2.bundle origin/master..master origin/HEAD..HEAD
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 415 bytes | 415.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)

"pull" cambia nel primo repository:

repo2$ cd ../repo1

repo1$ git pull /tmp/2.bundle 
Receiving objects: 100% (3/3), done.
From /tmp/2.bundle
 * branch            HEAD       -> FETCH_HEAD
Updating c8b9ff9..250d387
Fast-forward
 1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

repo1$ cat 1
2

A differenza del primo bundle, il secondo contiene solo una cronologia parziale di Git e non è direttamente clonabile:

repo1$ cd ..

gitbundletest$ git clone /tmp/2.bundle repo3
Cloning into 'repo3'...
error: Repository lacks these prerequisite commits:
error: c8b9ff94942039469fa1937f6d38d85e0e39893a 
fatal: bad object 250d38747656401e15eca289a27024c61e63ed68
fatal: remote did not send all necessary objects

C'è uno svantaggio nell'uso dei bundle che è necessario specificare manualmente quale intervallo di commit dovrebbe contenere ciascun bundle. Diversamente git push, git bundlenon tiene traccia di ciò che era nel pacchetto precedente, è necessario regolare manualmente refs/remotes/origin/mastero i pacchetti sarebbero più grandi di quanto potrebbero essere.


Non dimenticare di menzionare la --allbandiera per ottenere tutto. Se il repository è abbastanza piccolo, questo è il processo più semplice in quanto trasferisci semplicemente tutto ogni volta! Basta non perdere la memory stick - probabilmente il più grande problema di sicurezza!
Philip Oakley,

7

Devi prima installare Git . Quindi per creare un nuovo repository, esegui all'interno della cartella che hai copiato:

git init

Quindi puoi aggiungere i file che vuoi controllare con la versione git add(aggiungi -aper tutti i file) e iniziare a confermare le modifiche ( git commit).

Non è necessario eseguire il push su nessun telecomando, poiché è possibile lavorare sulla cronologia locale ( git log).

Per ulteriori informazioni, controllare:


Spingendo / tirando senza internet

Utilizzando il git pushcomando, è possibile eseguire il push su SSH (tramite connessione locale, intranet):

git remote add server ssh://[user@]host.xz[:port]/path/to/dev/repo.git/
git push server

o spingendo nella cartella:

git push /mnt/usb/my_repo

Ciò presuppone che tu abbia due copie del tuo repository.

Lo stesso vale per il tiro, ad es

git pull /mnt/usb/my_repo

patching

Per applicare le patch, è possibile utilizzare il patchcomando o git apply.

Vedi: Crea patch o file diff dal repository git e applicalo a un altro repository git diverso .


5

Puoi usare Git anche localmente. Quindi i tuoi commit vengono memorizzati solo localmente e hai ancora il controllo della versione con esso (e puoi diff / unire ecc.), Ma non puoi accedere al repository da nessun altro computer.

È possibile avviare un repository Git locale eseguendolo git initnella cartella locale. Come descritto qui .


3
che conosco, ma voglio lavorare su un altro computer e applicarlo ai file sul server senza accesso a Internet
Tutu Kaeen,

2
@TutuKaeen Non vedo nulla di male nell'avere il repository su un'unità flash e nel clonarlo / sincronizzarlo su hard disk di computer diversi. Tuttavia, "server senza accesso a Internet" sembra strano, l'obiettivo di un server è quello di fornire un servizio, il più delle volte il servizio è legato alla rete (ma non sempre, anzi).
AnonymousLurker,

2
@dhae - Ti preghiamo di dedicare qualche istante a fornire maggiori dettagli su come usare Git localmente. Solo indicare che può essere fatto non è utile per una risposta.
Ramhound,

2
@anonymousLurker il servizio sta fornendo dati a rete chiusa in istituzioni molto importanti. Semplicemente non serve nulla alla grande Internet, poiché i dati sono molto delicati e solo per i dipendenti.
Tutu Kaeen,

1
@TutuKaeen: Se ha alcun accesso alla rete, si può sempre eseguire il proprio server Git tramite SSH. C'è di più in Git oltre a GitHub.
Grawity,
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.