Come lavoro con un repository git all'interno di un altro repository?


284

Ho un repository multimediale Git in cui sto conservando tutti i miei file e script master JavaScript e CSS che userò su vari progetti.

Se creo un nuovo progetto che si trova nel proprio repository Git, come posso utilizzare i file JavaScript dal mio repository multimediale nel mio nuovo progetto in modo tale da non dover aggiornare entrambe le copie dello script quando apporto le modifiche ?


Si prega di vedere la risposta sottostruttura di seguito da @ ruslan-kabalin. Nota: gli hook pre-commit (o overcommit ) sono un modo per gestire l'obiezione sollevata da Robert Dundon
Hedgehog il

Risposte:


348

La chiave è i sottomoduli git .

Inizia a leggere il capitolo Sottomoduli del Git Community Book o del Manuale dell'utente

Supponi di avere un repository PROJECT1, PROJECT2 e MEDIA ...

cd /path/to/PROJECT1
git submodule add ssh://path.to.repo/MEDIA
git commit -m "Added Media submodule"

Ripeti sull'altro repository ...

Ora, il bello è che ogni volta che commetti modifiche a MEDIA, puoi farlo:

cd /path/to/PROJECT2/MEDIA
git pull
cd ..
git add MEDIA
git commit -m "Upgraded media to version XYZ"

Ciò ha appena registrato il fatto che il sottomodulo MEDIA WITHIN PROJECT2 è ora alla versione XYZ.

Ti dà il 100% di controllo su quale versione di MEDIA utilizza ogni progetto. i sottomoduli git sono fantastici, ma è necessario sperimentarli e conoscerli.

Con grande potenza arriva la grande possibilità di farsi mordere nella groppa.


Questo flusso di lavoro mi ricorda di utilizzare un modulo NPM privato stackoverflow.com/questions/7575627/...
cyrf

Se si preferisce che l'impostazione predefinita sia l'ultima versione, è possibile aggiungere uno script per propagare il commit MEDIA a tutti i progetti dipendenti.
jiggunjer,

3
Come si integra con github?
theonlygusti,

27

Prendi in considerazione l'utilizzo di sottostruttura anziché di sottomoduli, renderà la vita degli utenti repo molto più semplice. È possibile trovare una guida più dettagliata nel libro Pro Git .


6
Ecco un altro articolo informativo su sottostruttura vs sottomodulo: blogs.atlassian.com/2013/05/…
Benny Neugebauer,

3
Per quell'articolo, uno degli svantaggi è:> La responsabilità di non mescolare il codice super e il sotto-progetto in commit è a tuo carico. Nessuno ha tempo per questo (IMO)
Robert Dundon,

20

Se capisco bene il tuo problema, vuoi le seguenti cose:

  1. Conserva i tuoi file multimediali in un unico repository git, utilizzato da molti progetti
  2. Se modifichi un file multimediale in uno qualsiasi dei progetti nel tuo computer locale, dovrebbe apparire immediatamente in ogni altro progetto (quindi non vuoi impegnarti + push + pull tutto il tempo)

Sfortunatamente non esiste una soluzione definitiva per quello che vuoi, ma ci sono alcune cose per cui puoi semplificarti la vita.

Per prima cosa dovresti decidere una cosa importante: vuoi archiviare per ogni versione nel repository del tuo progetto un riferimento alla versione dei file multimediali? Ad esempio, se hai un progetto chiamato esempio.com, devi sapere quale style.css ha usato 2 settimane fa o l'ultimo è sempre (o principalmente) il migliore?

Se non è necessario saperlo, la soluzione è semplice:

  1. creare un repository per i file multimediali e uno per ciascun progetto
  2. creare un collegamento simbolico nei progetti che punta al repository multimediale clonato localmente. Puoi creare un relativo link simbolico (es. ../Media) e supporre che tutti controlleranno il progetto in modo che la directory media sia nello stesso posto, o scrivere il nome del link simbolico in .gitignore, e tutti possono decidere dove mette i file multimediali.

Nella maggior parte dei casi, tuttavia, si desidera conoscere queste informazioni sul controllo delle versioni. In questo caso hai due scelte:

  1. Archivia ogni progetto in un grande repository. Il vantaggio di questa soluzione è che avrai solo 1 copia del repository multimediale. Il grande svantaggio è che è molto più difficile passare da una versione all'altra del progetto (se si effettua il checkout a una versione diversa, si modificheranno sempre TUTTI i progetti)

  2. Usa i sottomoduli (come spiegato nella risposta 1). In questo modo memorizzerete i file multimediali in un repository e i progetti conterranno solo un riferimento a una versione specifica del repository multimediale. Ma in questo modo normalmente avrai molte copie locali del repository multimediale e non potrai facilmente modificare un file multimediale in tutti i progetti.

Se fossi in te probabilmente sceglierei la prima o la terza soluzione (collegamenti simbolici o sottomoduli). Se scegli di utilizzare i sottomoduli puoi comunque fare molte cose per semplificarti la vita:

  1. Prima di eseguire il commit è possibile rinominare la directory del sottomodulo e inserire un collegamento simbolico a una directory multimediale comune. Quando sei pronto per eseguire il commit, puoi rimuovere il link simbolico e rimuovere nuovamente il sottomodulo, quindi eseguire il commit.

  2. Puoi aggiungere una delle tue copie del repository multimediale come repository remoto a tutti i tuoi progetti.

È possibile aggiungere directory locali come telecomando in questo modo:

cd /my/project2/media
git remote add project1 /my/project1/media

Se modifichi un file in / my / project1 / media, puoi eseguirne il commit ed estrarlo da / my / project2 / media senza inviarlo a un server remoto:

cd /my/project1/media
git commit -a -m "message"
cd /my/project2/media
git pull project1 master

Sei libero di rimuovere questi commit in seguito (con git reset) perché non li hai condivisi con altri utenti.


1
per i progetti relativi al web in cui lavori all'interno della wwwcartella di Apache , dovresti inserire un .htaccessfile nella radice della wwwcartella o del tuo progetto, con Options +FollowSymLinksal suo interno, o meglio ancora <IfModule mod_rewrite.c>{new line}Options +FollowSymLinks{new line}RewriteEngine on{new line}</IfModule> (sostituisci {new line}con la nuova

3

Ho avuto problemi con sottotitoli e sottomoduli che le altre risposte suggeriscono ... principalmente perché sto usando SourceTree e sembra abbastanza difettoso.

Invece, ho finito con l'utilizzo di SymLinks e sembra funzionare bene, quindi sto pubblicandolo qui come possibile alternativa.

C'è una guida completa qui: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/

Ma in pratica devi solo mklink i due percorsi in un prompt dei comandi con privilegi elevati. Assicurati di utilizzare il prefisso hard link / J. Qualcosa del genere: mklink / JC: \ projects \ MainProject \ plugins C: \ projects \ SomePlugin

Puoi anche usare i relativi percorsi delle cartelle e metterlo in una mazza per essere eseguito da ogni persona quando controlla per la prima volta il tuo progetto.

Esempio: mklink / J. \ Assets \ TaqtileTools .. \ TaqtileHoloTools

Una volta che la cartella è stata collegata, potrebbe essere necessario ignorare la cartella all'interno del repository principale a cui fa riferimento. Altrimenti sei a posto.

Nota Ho eliminato la mia risposta duplicata da un altro post poiché quel post è stato contrassegnato come domanda duplicata a questo post.

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.