Close

Subárvore Git: a alternativa ao submódulo Git

Foto profissional de Nicola Paolucci
Nicola Paolucci

Representante do desenvolvedor


A Internet está repleta de artigos sobre por que você não deve usar os submódulos do Git. Embora os submódulos sejam úteis para alguns casos de uso, eles têm várias desvantagens.

Existem alternativas? A resposta é: sim! Existem (pelo menos) duas ferramentas que podem ajudar a rastrear o histórico de dependências de software em seu projeto, permitindo que você continue usando o Git:

  • Subárvore do Git
  • Repositório do Google

Neste post, vou analisar o git subtree e mostrar por que é uma melhoria – embora não perfeita – em relação ao git submodule.

O que é git subtree e por que devo usar?


O git subtree permite aninhar o repositório dentro de outro como um subdiretório. É uma das várias maneiras pelas quais os projetos Git podem gerenciar as dependências do projeto.

Diagrama de subárvore Antes/Depois do Git

Por que você pode querer considerar o git subtree

  • O gerenciamento de um fluxo de trabalho simples é fácil.
  • As versões mais antigas do Git são suportadas (ainda mais antigas que a v1.5.2).
  • O código do subprojeto está disponível logo após a conclusão do clone do superprojeto.
  • O git subtree não exige que os usuários do repositório aprendam nada de novo. Eles podem ignorar o fato de que você está usando um git subtree para gerenciar dependências.
  • A subárvore do git não adiciona novos arquivos de metadados como o submódulo do git faz (ou seja, .gitmodule).
  • O conteúdo do módulo pode ser modificado sem ter uma cópia separada do repositório da dependência em outro lugar.

Desvantagens (mas, em nossa opinião, são aceitáveis):

  • Você deve aprender uma nova estratégia de merge (git subtree).
  • Contribuir com o código de volta para os subprojetos é um pouco mais complicado.
  • A responsabilidade de não misturar o código do superprojeto e do subprojeto nos commits é sua.
bancos de dados
Material relacionado

Como mover um Repositório do Git completo

Logotipo do Bitbucket
VER SOLUÇÃO

Aprenda a usar o Git com o Bitbucket Cloud

Como usar o git subtree


O git subtree está disponível na versão stock do Git desde maio de 2012 — v1.7.11 e superior. A versão instalada pelo Homebrew no OSX já tem uma subárvore conectada, mas, em algumas plataformas, você pode precisar seguir as instruções de instalação.

Deixe-me mostrar o exemplo canônico de rastreamento de um plugin do Vim usando o git subtree.

O caminho rápido e sujo sem rastreamento remoto

Se você quiser apenas alguns forros para cortar e colar, basta ler este parágrafo. Primeiro, adicione git subtree em uma pasta de prefixo especificada:

git subtree add --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash

(A prática comum é não armazenar todo o histórico do subprojeto no repositório principal, mas se você quiser que ele seja preservado, basta omitir a marcação –squash.)

O comando acima produz esta saída:

git fetch https://bitbucket.org/vim-plugins-mirror/vim-surround.git main
warning: no common commits
remote: Counting objects: 338, done.
remote: Compressing objects: 100% (145/145), done.
remote: Total 338 (delta 101), reused 323 (delta 89)
Receiving objects: 100% (338/338), 71.46 KiB, done.
Resolving deltas: 100% (101/101), done.
From https://bitbucket.org/vim-plugins-mirror/vim-surround.git
* branch main -} FETCH_HEAD
Added dir '.vim/bundle/tpope-vim-surround'

Como você pode ver, essa ação registra um merge commit ao condensar todo o histórico do repositório vim-surround em um:

1bda0bd [3 minutes ago] (HEAD, stree) Merge commit 'ca1f4da9f0b93346bba9a430c889a95f75dc0a83' as '.vim/bundle/tpope-vim-surround' [Nicola Paolucci]
ca1f4da [3 minutes ago] Squashed '.vim/bundle/tpope-vim-surround/' content from commit 02199ea [Nicola Paolucci]

Se depois de um tempo você quiser atualizar o código do plugin do repositório upstream, você pode fazer um git subtree pull:

git subtree pull --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash

É muito rápido e tranquilo, mas os comandos são um pouco longos e difíceis de lembrar. Podemos tornar os comandos mais curtos adicionando o subprojeto como um controle remoto.

Adicionando o subprojeto como um controle remoto

Adicionar a subárvore como um controle remoto nos permite consultá-la de forma mais curta:

git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git

Agora podemos adicionar a subárvore (como antes), mas agora podemos nos referir ao controle remoto de forma resumida:

git subtree add --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash

O comando para atualizar o subprojeto posteriormente se torna:

git fetch tpope-vim-surround main
git subtree pull --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash

Contribuindo de volta ao upstream

Agora a gente tem liberdade para fazer o commit das correções para o subprojeto no diretório de trabalho local. Quando é hora de contribuir de volta para o projeto upstream, precisamos bifurcar o projeto e adicioná-lo como outro controle remoto:

git remote add durdn-vim-surround ssh://git@bitbucket.org/durdn/vim-surround.git

Agora podemos usar o comando subtree push como o seguinte:

git subtree push --prefix=.vim/bundle/tpope-vim-surround/ durdn-vim-surround main
git push using: durdn-vim-surround main
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 308 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
To ssh://git@bitbucket.org/durdn/vim-surround.git
02199ea..dcacd4b dcacd4b21fe51c9b5824370b3b224c440b3470cb -} main

Depois disso, estamos prontos e podemos abrir um pull request para o mantenedor do pacote.

Posso fazer a mesma coisa sem usar o comando git subtree?

Sim! Sim, você pode. O git subtree é diferente da estratégia de merge de subárvore. Você ainda pode usar a estratégia de merge, mesmo que por algum motivo o git subtree não esteja disponível. Veja como:

Adicione a dependência como um simples git remote:

git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git

Antes de ler o conteúdo da dependência no repositório, é importante gravar um merge para que possamos rastrear todo o histórico da árvore do plug-in até este ponto:

git merge -s ours --no-commit tpope-vim-surround/main

Quais saídas:

Automatic merge went well; stopped before committing as requested

Em seguida, lemos o conteúdo do objeto de árvore mais recente no repositório de plugins no diretório de trabalho pronto para o commit:

git read-tree --prefix=.vim/bundle/tpope-vim-surround/ -u tpope-vim-surround/main

Agora podemos fazer o commit (e vai ser um commit de merge que vai preservar o histórico da árvore que lemos):

git ci -m"[subtree] adding tpope-vim-surround"
[stree 779b094] [subtree] adding tpope-vim-surround

Quando for atualizar o projeto, agora é possível extrair usando a estratégia de merge de git subtree:

git pull -s subtree tpope-vim-surround main

O git subtree é uma excelente alternativa


Depois de ter usado os submódulos git por um tempo, você vai ver que o git subtree resolve muitos dos problemas com o submódulo do git. Como de costume, com todas as coisas do Git, há uma curva de aprendizado para aproveitar ao máximo a função.

Me siga no Twitter @durdn para saber mais sobre o Git. E confira o Atlassian Bitbucket se você estiver procurando uma boa ferramenta para gerenciar os repositórios do Git.

Atualização: depois de publicar este artigo, também escrevi um artigo sobre o poder da subárvore do Git.

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


Compartilhar este artigo
Próximo tópico

Leitura recomendada

Marque esses recursos para aprender sobre os tipos de equipes de DevOps ou para obter atualizações contínuas sobre DevOps na Atlassian.

Pessoas colaborando usando uma parede cheia de ferramentas

Blog do Bitbucket

Ilustração do DevOps

Caminho de aprendizagem de DevOps

Demonstrações de funções no Demo Den com parceiros da Atlassian

Como o Bitbucket Cloud funciona com o Atlassian Open DevOps

Inscreva-se para receber a newsletter de DevOps

Thank you for signing up