Layout del repository GIT per server con più progetti


96

Una delle cose che mi piace del modo in cui ho configurato Subversion è che posso avere un unico repository principale con più progetti. Quando voglio lavorare su un progetto posso controllare solo quel progetto. Come questo

\main
    \ProductA
    \ProductB
    \Shared

poi

svn checkout http://.../main/ProductA

Come nuovo utente di git, voglio esplorare un po 'di best practice sul campo prima di impegnarmi in un flusso di lavoro specifico. Da quello che ho letto finora, git memorizza tutto in una singola cartella .git nella radice dell'albero del progetto. Quindi potrei fare una delle due cose.

  1. Imposta un progetto separato per ogni prodotto.
  2. Crea un unico grande progetto e archivia i prodotti in sottocartelle.

Ci sono dipendenze tra i prodotti, quindi il singolo grande progetto sembra appropriato. Useremo un server in cui tutti gli sviluppatori possono condividere il loro codice. Ho già funzionato su SSH e HTTP e quella parte che amo. Tuttavia, i repository in SVN hanno già una dimensione di molti GB, quindi trascinare l'intero repository su ogni macchina sembra una cattiva idea, soprattutto perché ci viene addebitata un'eccessiva larghezza di banda di rete.

Immagino che i repository del progetto del kernel Linux siano ugualmente grandi, quindi deve esserci un modo corretto di gestirlo con Git, ma non l'ho ancora capito.

Esistono linee guida o best practice per lavorare con repository multi-progetto di grandi dimensioni?

Risposte:


65

La linea guida è semplice, per quanto riguarda i limiti di Git :

  • un repo per progetto
  • un progetto principale con sottomoduli .

L'idea non è quella di memorizzare tutto in un gigantesco repository git, ma costruire un piccolo repository come progetto principale, che farà riferimento ai giusti commit di altri repository, ognuno dei quali rappresenta un progetto o un suo componente comune.


L' OP Paul Alexander commenta :

Questo suona simile al supporto "esterno" fornito da subversion.
Abbiamo provato questo e abbiamo trovato estremamente macchinoso aggiornare costantemente i riferimenti di versione negli esterni poiché i progetti vengono sviluppati in concomitanza con le dipendenze l'uno dall'altro. C'è un'altra opzione?

@Paul: sì, invece di aggiornare la versione dal progetto principale, puoi:

  • sviluppare i tuoi sottoprogetti direttamente dall'interno del progetto principale (come spiegato in "La vera natura dei sottomoduli "),
  • oppure fai riferimento in un sub-repo e originverso lo stesso sub-repo in fase di sviluppo altrove: da lì devi solo estrarre da quel sub-repo le modifiche apportate altrove.

In entrambi i casi, non devi dimenticare di eseguire il commit del progetto principale, per registrare la nuova configurazione. Nessuna proprietà "esterna" da aggiornare qui. L'intero processo è molto più naturale.

Onestamente, questo suona come un vero dolore e tutto ciò che richiede agli sviluppatori di fare qualcosa manualmente ogni volta sarà solo una fonte regolare di bug e manutenzione.
Suppongo che cercherò di automatizzare questo con alcuni script nel super progetto.

Ho risposto:

Onestamente, potresti aver avuto ragione ... cioè fino all'ultima versione di Git 1.7.1 .
git diffed git statusentrambi hanno imparato a tenere conto degli stati dei sottomoduli anche se eseguiti dal progetto principale.
Semplicemente non puoi perdere la modifica del sottomodulo.

Detto ciò:


Vale anche la pena notare che se includi sottomoduli nel progetto principale, ogni sottomodulo è il proprio repository git, quindi sei libero di includere versioni particolari dei sottomoduli, determinati tag, ecc.
Damien Wilson

1
@VonC: suona in modo simile al supporto "externals" fornito da subversion. Abbiamo provato questo e abbiamo trovato estremamente macchinoso aggiornare costantemente i riferimenti di versione negli esterni poiché i progetti vengono sviluppati in concomitanza con le dipendenze l'uno dall'altro. C'è un'altra opzione?
Paul Alexander

@Paul: sì, invece di aggiornare la versione dal progetto principale, sviluppi i tuoi sottoprogetti direttamente dall'interno del progetto principale (vedi stackoverflow.com/questions/1979167/git-submodule-update/… ), o fai riferimento in un sub-repo un'origine verso lo stesso sub-repo che si sta sviluppando altrove: da lì devi solo estrarre da quel sub-repo le modifiche apportate altrove. In entrambi i casi, non devi dimenticare di eseguire il commit del progetto principale, per registrare la nuova configurazione. nessuna proprietà "esterna" da aggiornare. L'intero processo è molto più naturale.
VonC

3
@Paul: onestamente, potresti avere ragione ... questo fino all'ultima versione di Git 1.7.1. ( kernel.org/pub/software/scm/git/docs/RelNotes-1.7.1.txt ) git diffed git statusentrambi hanno imparato a tenere conto degli stati dei sottomoduli anche se eseguiti dal progetto principale. Semplicemente non puoi perdere la modifica del sottomodulo.
VonC

1
Fino a quando @PaulAlexander non dice qualcosa, scelgo di credere che stia effettivamente usando i sottomoduli ora.
cregox

2

GitSlave ti consente di gestire diversi repository indipendenti come uno solo. Ogni repo può essere manipolato da normali comandi git, mentre gitslave ti consente di eseguire anche un comando su tutti i repository.

super-repo
+- module-a-repo
+- module-b-repo

gits clone url-super-repo
gits commit -a -m "msg"

Repo-per-project presenta vantaggi con la componentizzazione e build semplificate con strumenti come Maven. Repo-per-project aggiunge protezione limitando l'ambito di ciò che lo sviluppatore sta cambiando, in termini di commit errati di spazzatura.


Potresti includere qualcosa sui pro e contro del sottomodulo gitslave e git?
MM

1
Il grande vantaggio di Gitslave è che lascia i tuoi repository Git da soli. Puoi gestire i repository con semplici comandi git senza influire sulla relazione gitslave. Ma quando si desidera eseguire un tag, ad esempio, su tutti i repository, gitslave può farlo.
Andre

1
Il sottomodulo, secondo me, è irto di complessità. Gli sviluppatori devono capirlo e lavorarci intimamente.
Andre
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.