Skip to main content

Sobre merges de subárvore do Git

Platform navigation

Normalmente, um merge de subárvore é usado para conter um repositório dentro de outro repositório. O "sub-repositório" é armazenado em uma pasta do repositório principal.

A melhor maneira de explicar merges de subárvore é mostrar com exemplo. O que faremos:

  • Criar um repositório vazio chamado test que representa o projeto.
  • Mesclar outro repositório nele como uma subárvore chamada Spoon-Knife.
  • O projeto test usará esse subprojeto como se ele fizesse parte do mesmo repositório.
  • Efetuar fetch das atualizações de Spoon-Knife para o projeto test.

  1. Abra TerminalTerminalGit Bash.

  2. Crie um novo diretório e navegue até ele.

    mkdir test
    cd test
    
  3. Inicialize um novo repositório Git.

    $ git init
    > Initialized empty Git repository in /Users/octocat/tmp/test/.git/
    
  4. Crie e faça commit de um novo arquivo.

    $ touch .gitignore
    $ git add .gitignore
    $ git commit -m "initial commit"
    > [main (root-commit) 3146c2a] initial commit
    >  0 files changed, 0 insertions(+), 0 deletions(-)
    >  create mode 100644 .gitignore
    

  1. Adicione uma nova URL remota apontando para o projeto separado em que estávamos interessados.

    $ git remote add -f spoon-knife https://.com/octocat/Spoon-Knife.git
    > Updating spoon-knife
    > warning: no common commits
    > remote: Counting objects: 1732, done.
    > remote: Compressing objects: 100% (750/750), done.
    > remote: Total 1732 (delta 1086), reused 1558 (delta 967)
    > Receiving objects: 100% (1732/1732), 528.19 KiB | 621 KiB/s, done.
    > Resolving deltas: 100% (1086/1086), done.
    > From https://.com/octocat/Spoon-Knife
    >  * [new branch]      main     -> Spoon-Knife/main
    
  2. Mesclar o projeto Spoon-Knife no projeto local do Git. Isso não muda qualquer um de seus arquivos localmente, mas prepara o Git para a próxima etapa.

    Se você estiver usando o Git 2.9 ou superior:

    $ git merge -s ours --no-commit --allow-unrelated-histories spoon-knife/main
    > Automatic merge went well; stopped before committing as requested
    

    Se estiver usando o Git 2.8 ou abaixo:

    $ git merge -s ours --no-commit spoon-knife/main
    > Automatic merge went well; stopped before committing as requested
    
  3. Crie um diretório chamado spoon-knife e copie o histórico do Git do projeto Spoon-Knife para ele.

    $ git read-tree --prefix=spoon-knife/ -u spoon-knife/main
    > fatal: refusing to merge unrelated histories
    
  4. Faça commit das alterações para mantê-las seguras.

    $ git commit -m "Subtree merged in spoon-knife"
    > [main fe0ca25] Subtree merged in spoon-knife
    

Embora tenhamos adicionado apenas um subprojeto, qualquer número de subprojetos pode ser incorporado a um repositório Git.

Dica

Se você criar um clone do repositório no futuro, os repositórios remotos adicionados não serão criados para você. Você precisará adicioná-los novamente usando o comando git remote add.

Quando um subprojeto é adicionado, ele não é mantido automaticamente em sincronia com as alterações de upstream. Você precisará atualizar o subprojeto com o seguinte comando:

git pull -s subtree REMOTE-NAME BRANCH-NAME

Para o exemplo acima, o comando seria:

git pull -s subtree spoon-knife main