Caio Lente

Submódulos no Git

· Caio Lente

Ano passado, o time da Curso-R se reuniu para conversar sobre a nova estrutura dos nossos cursos. Um dos pontos da pauta era a organização dos nossos repositórios que, ao longo dos anos, foi ficando cada vez mais difícil de manter.

Cada oferecimento de cada curso tem um repositório no GitHub, o que nos permite personalizar o conteúdo de uma turma sem afetar as outras. Mas essa granularidade cria um problema: o que fazer com o material que é comum a todas as turmas de um mesmo curso?

O problema

Imagine que existe uma turma A, que participou do curso R para Ciência de Dados III este ano, e uma turma B, que vai fazer o curso no ano que vem.

No passado nós copiávamos todo o conteúdo do repo A para o repo B, mas hoje em dia nós criamos os repositórios dos cursos com antecedência. Isso significa que qualquer alteração no material durante o oferecimento A precisaria ser propagada cuidadosamente para para o oferecimento B; infelizmente isso pode dar muito trabalho.

A solução que encontramos foi criar um repositório main para cada curso, ou seja, um repo central que contém apenas os slides. Assim, os repos das turmas só precisam hospedar o conteúdo que muda de um oferecimento para o outro (exercícios, anexos, comentários, etc.) e qualquer alteração nos slides imediatamente se aplica a todos os repos satélites.

Tudo funcionou perfeitamente bem até que decidimos fazer a primeira mudança na ementa de um curso. O problema desta estratégia é qualquer alteração no main é propagada para o passado; logo, se durante o oferecimento B resolvermos fazer uma reestruturação grande no material, a turma A vai perder a versão dela e ficará sem as suas referências.

O ideal seria ter uma maneira de atualizar os slides seletivamente, ou seja, manter a turma A na versão anterior do main e passar a B para a versão nova. Isso tudo sem quebrar os repos feitos com antecedência.

Submódulos

É aí que entram os submódulos. De acordo com a documentação, eles são essencialmente repos dentro de outros repos, ou seja, clonamos um repo (o submódulo) dentro de um repo hospedeiro. Inception.

Como eu posso usar submódulos para resolver meu problema com as turmas? Eu posso continuar usando o repo main para armazenar os slides, mas, ao invés de deixá-lo isolado, ele seria clonado como submódulo dentro do repo de cada turma. Neste arranjo, eu posso apontar o submódulo da turma A para a versão antiga do main e manter o da turma B apontado para a versão mais nova.

Para começar a usar submódulos, eu recomendo executar os seguintes comandos Git, pois eles garantem que o seu ambiente estará adequadamente preparado:

git config --global submodule.recurse true
git config --global push.recurseSubmodules check

Agora, dentro do repositório desejado, eu posso rodar o comando abaixo para trazer o repo main como um submódulo:

git submodule add https://github.com/curso-r/main-r4ds-3.git materiais/

Isso é muito similar a fazer um clone normal! No caso, o repositório main-r4ds-3 será clonado na pasta materiais/ no repo hospedeiro.

A partir de agora, eu posso usar sempre o repo hospedeiro, sem me preocupar com o main. Se eu fizer uma alteração na pasta materiais/, basta fazer um commit como qualquer outro! A atualização não vai para o repo da turma, mas sim para o main.

cd materiais/
git add -A
git commit -m "Alteração no main"
git push

Se voltarmos para a pasta um nível acima e executarmos git status, vamos ver que houve uma alteração em um arquivo chamado .gitmodules. Isso quer dizer que o submódulo foi atualizado no GitHub, não que ele foi atualizado no repo da turma.

Este é o pulo do gato: podemos atualizar o main quantas vezes quisermos, mas as atualizações só serão propagadas para o repo da turma se aceitarmos a alteração.

cd ../
git status
git add -A
git commit -m "Aceitando alterações do main"
git push

Isso permite que o repo de uma turma antiga como a A mantenha a sua referência a uma versão anterior do main ao mesmo passo que o repo das turmas novas podem ter suas referências atualizadas com facilidade. Se você quiser um exemplo de como fica uma referência no GitHub, dê uma olhada na demo de submódulos que fizemos na Curso-R: https://github.com/curso-r/202211-demo-submod.

E isso é tudo. Se você quiser uma demonstração em vídeo, a referência que eu usei foi essa aqui do Redhwan Nacef. Se você tiver qualquer dúvida, mande um email para mim e eu vou tentar ajudar o máximo possível. Até a próxima!

#git #cs

Responda a este post por email ↪