Passos para converter multi-repo para mono-repo

5

Quais são os melhores passos para converter multi-repos em um mono-repo?

Isso é o que eu tenho até agora:

  1. para cada repo, confira a filial mais recente (ramo de integração, geralmente)
  2. para cada repo, copie a pasta repo para o novo git repo (o repo mono)
  3. para cada pasta, exclua a antiga pasta .git
  4. Organize todos os arquivos, confirme e envie o novo mono-repo

Minha única pergunta no momento - os arquivos .gitignore existentes funcionarão corretamente para as subpastas no novo mono-repo?

    
por MrCholo 30.09.2018 / 00:19
fonte

1 resposta

8

Não copie os arquivos, mescle os repositórios. O Git não faz grande diferença entre “repositório diferente” e “ramo diferente”. Mais precisamente, um repositório é uma coleção de tags e branches. Eu suponho que você queira mesclar o ramo mestre de todos os repositórios.

Abordagem geral (mas veja a discussão sobre git-subtree abaixo):

  1. Pense no layout do seu monorepo. Presumo que, para o início, você terá cada repositório atual como uma subpasta do monorepo para evitar conflitos.

  2. Para cada repositório atual, mova o conteúdo do repositório para uma subpasta e confirme a alteração. Você pode usar o comando git mv para fazer isso facilmente.

    Por exemplo se o seu componente é chamado libfoo e você atualmente tem esse layout de repositório:

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

    Em seguida, podemos movê-lo para uma pasta libfoo/ :

    libfoo/
      Makefile
      README.txt
      src/
        ...
      include/
        ...
    
  3. Crie um novo repositório para o seu monorepo e adicione todos os repos existentes como um "remoto". Apesar de seu nome, um repositório remoto pode ser um caminho para algum diretório no mesmo sistema de arquivos. Então, git fetch --all usa remotamente para carregar seu histórico no banco de dados git do monorepo. Depois, você pode listar todas as ramificações com git branch --all . Isso será parecido com:

    * master
      remotes/libfoo/master
      remotes/libbar/master
      ...
    
  4. Para cada controle remoto, mescle seu ramo mestre. Não deve haver conflitos porque tudo está em um diretório separado.

  5. Agora você terminou e você tem um monorepo sem perda de histórico. Você pode remover os controles remotos.

Mas cuidado: você só pode mesclar uma ramificação de cada repositório. Se um dos repositórios originais tiver vários ramos, eles não poderão mais ser mesclados sem conflitos excessivos. Considere reformulá-los depois de mover o conteúdo do repositório em uma pasta, mas antes de mesclar tudo no monorepo.

Na prática, você pode usar git subtree para automatizar a maioria dessas etapas. O comando subtree permite que você mescle um ramo específico em um diretório específico.

  1. inicializa o monorepo e faz pelo menos um commit
  2. para cada repositório existente, adicione-o como uma subárvore, por exemplo:

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

    O -P / --prefix é o diretório sob o qual o conteúdo do repositório deve ser adicionado. No lugar do caminho para um repositório, qualquer URL de repositório pode ser usado. Por padrão, isso adicionará o histórico completo, ou você poderá --squash do histórico em um único commit.

O Git-subtree é uma ferramenta extremamente poderosa para manipular monorepos. Você também pode extrair um diretório em um repositório separado ( git subtree push ) ou mesclar atualizações do repositório original ( git subtree pull ). Por exemplo, você pode usar isso para traduzir diferentes ramificações.

  • Para traduzir uma ramificação feature :
  • Crie uma nova ramificação no monorepo: git checkout -b feature
  • Puxe as alterações do feature da libfoo para o diretório correto do monorepo: git subtree pull -P libfoo/ ../path/to/libfoorepo feature .
  • Opcional: rebaixe o ramo para mestre para simplificar o gráfico do histórico.

Mas considere se um monorepo é realmente apropriado para seu caso de uso. Pode ainda ser desejável ter repositórios diferentes disponíveis independentemente. O contendor principal é git submodules, onde um repositório é montado como um subdiretório de outro. No entanto, a experiência não é perfeita. O histórico da ramificação não é compartilhado com o submódulo. Se você editar o código em um submódulo, terá que confirmar esse trabalho separadamente. Os submódulos Git são mais úteis para “vender” dependências externas que são fixadas em uma versão específica, não para desenvolvimento combinado.

Qualquer que seja a abordagem que você usar, os arquivos gitignore continuarão a funcionar, porque quaisquer padrões são correspondidos em relação ao arquivo gitignore. Um repositório pode conter vários arquivos gitignore.

    
por 30.09.2018 / 12:03
fonte

Tags