Passaggi per convertire multi-repo in mono-repo

5

Quali sono i passi migliori per convertire i multi-repos in un mono-repo?

Questo è quello che ho finora:

  1. per ogni repo, controlla il ramo più recente (ramo di integrazione, di solito)
  2. per ogni repo, copia la cartella repo nel nuovo repository git (il repo mono)
  3. per ogni cartella, elimina la vecchia cartella .git
  4. Metti in scena tutti i file, esegui il commit e premi il nuovo repo mono

La mia unica domanda al momento - i file .gitignore esistenti funzioneranno correttamente per le sottocartelle nel nuovo mono-repo?

    
posta MrCholo 30.09.2018 - 00:19
fonte

1 risposta

8

Non copiare i file, ma unire i repository. Git non fa una grande differenza tra "repository differenti" e "filiali diverse". Più precisamente, un repository è una raccolta di tag e rami. Presumo che tu voglia unire il ramo principale di tutti i repository.

Approccio generale (ma vedi la discussione di git-sottoalbero di seguito):

  1. Pensa al layout del tuo monorepo. Suppongo che all'inizio, avrai ogni repository corrente come sottocartella del monorepo per evitare conflitti.

  2. Per ogni repository attuale, sposta il contenuto del repository in una sottocartella e conferma la modifica. Puoi usare il comando git mv per farlo facilmente.

    es. se il tuo componente è chiamato libfoo e attualmente disponi di questo layout del repository:

    Makefile
    README.txt
    src/
      ...
    include/
      ...
    

    Quindi potremmo spostarlo in una cartella libfoo/ :

    libfoo/
      Makefile
      README.txt
      src/
        ...
      include/
        ...
    
  3. Crea un nuovo repository per il tuo monorepo e aggiungi tutti i repository esistenti come "remoto". Nonostante il suo nome, un repository remoto può essere un percorso verso qualche directory sullo stesso file system. Quindi git fetch --all remoti per caricare la loro cronologia nel database git di monorepo. Successivamente, puoi elencare tutti i rami con git branch --all . Sembrerà:

    * master
      remotes/libfoo/master
      remotes/libbar/master
      ...
    
  4. Per ciascun telecomando, unisci il suo ramo principale. Non ci dovrebbero essere conflitti perché tutto è in una directory separata.

  5. Ora hai finito, e hai un monorepo senza perdita di cronologia. Puoi rimuovere i telecomandi.

Ma attenzione: puoi unire solo un ramo di ciascun repository. Se uno dei repository originali ha più rami, non possono più essere uniti senza conflitti eccessivi. Considera di ridistribuirli dopo aver spostato i contenuti del repository in una cartella, ma prima di unire tutto nel monorepo.

In pratica, puoi utilizzare git subtree per automatizzare la maggior parte di questi passaggi. Il comando sottostruttura consente di unire un ramo specifico in una directory specifica.

  1. inizializza il monorepo e crea almeno un commit
  2. per ogni repository esistente, aggiungilo come sottostruttura, ad esempio:

    git subtree add -P libfoo/ ../path/to/libfoorepo master
    

    Il -P / --prefix è la directory in cui deve essere aggiunto il contenuto del repository. Al posto del percorso di un repository, è possibile utilizzare qualsiasi URL di repository. Per impostazione predefinita, questo aggiungerà la cronologia completa, in alternativa puoi --squash della cronologia in un singolo commit.

Il sottoalbero di Git è uno strumento estremamente potente per manipolare i monoropos. Puoi anche estrarre una directory in un repository separato ( git subtree push ) o unire gli aggiornamenti dal repository originale ( git subtree pull ). Ad esempio, potresti usarlo per tradurre diversi rami.

  • Per tradurre un ramo feature :
  • Crea un nuovo ramo nel monorepo: git checkout -b feature
  • Tira le modifiche dal% co_de di libfoo alla directory corretta del monorepo: feature .
  • Opzionale: rebase il ramo sul master per semplificare il grafico della cronologia.

Ma considera se un monorepo è veramente appropriato per il tuo caso d'uso. Potrebbe essere comunque preferibile avere diversi repository disponibili indipendentemente. Il concorrente principale è git submodules, dove un repository è montato come sottodirectory di un altro. Tuttavia, l'esperienza non è perfetta. La cronologia del ramo non è condivisa con il sottomodulo. Se si modifica il codice in un sottomodulo, è necessario eseguire il commit separatamente. I sottomoduli Git sono molto utili per le dipendenze esterne "vendor" che vengono aggiunte a una versione specifica, non per lo sviluppo combinato.

Qualunque approccio tu usi, i file gitignore continueranno a funzionare perché tutti i pattern sono abbinati rispetto al file gitignore. Un repository può contenere più file gitignore.

    
risposta data 30.09.2018 - 12:03
fonte

Leggi altre domande sui tag