2015-12-08 27 views
7

Ho cercato un po 'e non ho trovato risposta (forse non so cosa guardare).Repository multipli con sottomodulo singolo

Abbiamo una libreria principale che è un repository (chiamiamolo Lib) che contiene la maggior parte dei nostri moduli e sottomoduli. Diciamo anche che ha una dimensione di 2 GB ...

Ora abbiamo molti progetti come: ProjA, ProjB, ProjC ognuno usa il Lib come sottomodulo.

proja

  • Lib (ramo: master, commettere #: 1)

ProjB

  • Lib (ramo: altro, impegnarsi #: 2)

ProjA

  • Lib (ramo: master, commettere #: 4)

Così, mentre io sono in grado di mantenere ogni progetto riferimento per correggere libreria (aka modulo) versione. Ora ho 3 * 2 GB = 6 GB di sottomodulo THE SAME.

C'è un modo per fare riferimento a un singolo sottomodulo pur mantenendo i file corretti/il controllo delle versioni di riferimento?

Es.

proja

  • Lib/base_lib.h (v1.0)

  • lib/file_only_in_this_commit

ProjB

  • Lib/base_l ib.h (v1.0)

ProjC

  • Lib/base_lib.h (v1.1)

Grazie!

+0

Non che io sappia. Per repository, puoi avere solo un riferimento a uno SHA in un sottomodulo, quindi il motivo per cui lo hai aggiunto 3 volte. Immagino che tu abbia questa configurazione perché 'ProjA',' ProjB' e 'ProjC' sono tutti collegati e interagiscono insieme? Altrimenti, questo potrebbe essere 3 diversi repository. Oppure potresti avere 3 rami in un repository, nel qual caso potresti avere diversi riferimenti di sottomodulo su ciascun ramo con una sola versione del sottomodulo – houtanb

+0

Se il tuo obiettivo è quello di risparmiare spazio, dopo il checkout iniziale sostituisci la directory degli oggetti con un clone hardlinked – basin

+0

@basin C'è un modo per definire tali hard link in git? Effettuare manualmente il tuo suggerimento in realtà non risolve il problema, e preferirei evitare anche gli script se possibile. – Danra

risposta

3

Bene, internamente l'intera operazione di sottomodulo è abbastanza semplice, quindi puoi padroneggiarlo secondo i tuoi gusti.

All'interno di ciascuna della Proj<N>/.git/modules/ c'è una cartella corrispondente Lib modulo con repository nudo clonato dal riferimento remoto specificato in Proj<N> /.gitmodules in Lib.url. Questi repository nudi sono i punti di ottimizzazione.

È possibile semplicemente ricrearli utilizzando collegamenti fisici ove possibile.

1) Creare una nuda clone del Lib in una cartella sullo stesso filesystem come i vostri tutti i pronti contro termine Proj:

git clone --bare url://to/Lib /path/to/Lib.git 

2) Sostituire repo modulo predefinito con il pronti contro termine, che fa riferimento al repo a nudo da p. 1:

mv ProjA/.git/modules/Lib ProjA/.git/modules/Lib.old // preserve it for a while 
git clone --bare --local url://to/Lib \ 
    --reference /path/to/Lib.git ProjA/.git/modules/Lib 

3) Ripristinare il config dal repository conservata in ProjA/.git/modules/Lib:

cp ProjA/.git/modules/Lib.old/config ProjA/.git/modules/Lib/config 

Ora è possibile verificare se tutto funziona in ProjA e rimuovere ProjA/.git/modules/Lib.old e così via. In questo caso tutti i repository useranno gli stessi file object.

In un particolare stato di un sottomodulo viene fatto riferimento da un SHA1 preciso. A meno che non eseguiate alcune operazioni "malvagie" nel repository principale Lib (ad esempio git filter-branch o altre operazioni che possono portare alla cancellazione di un commit), tutti i commit appropriati in Lib vengono mantenuti per sempre. Il tuo Proj<N> verifica particolari commit completamente indipendenti l'uno dall'altro, quindi non dovresti preoccuparti che uno stato di Lib in ProjA possa interferire con un altro stato di Lib in ProjB.

6

È possibile utilizzare git worktree (disponibile dal git 2.5) per creare worktrees supplementari per il modulo Lib, le posizioni all'interno proja, ProjB, ecc

Perché git worktree lo rende un dolore per fare diversi worktrees con lo stesso nome (tutti sono chiamati "Lib"), ho appena creato uno script, share_submodules per aggirare le difficoltà e creare l'albero di lavoro aggiuntivo invece di un sottomodulo, impostarlo sul commit del sottomodulo giusto e farlo in modo ricorsivo per tutti i sottomoduli all'interno del modulo condiviso.

Dovrebbe funzionare come se il sottomodulo fosse stato creato da git submodule update --init --recursive, tranne che tutte le copie si riferiscono agli oggetti di un modulo.

Se stai trasferendo ad essa rimuovendo il modulo, ci sono file di modulo randagi nel .git e ho creato find_stray_submodules.py per pulirli.

+0

Probabilmente, in questo caso lui/lei dovrebbe smettere completamente di usare 'git submodule's , no? – user3159253

+0

@ user3159253: questo ** dovrebbe ** essere compatibile con 'git submodule'. Sebbene potessi solo dirlo con grande sicurezza dopo aver usato questa soluzione per un po '(ho appena iniziato) – yairchu

Problemi correlati