synch - git submodules




atualização do submodule git (3)

Não estou claro sobre o que os meios a seguir (do git submodule update docs):

... fará com que os submódulos HEAD sejam desconectados, a menos que --rebase ou --merge seja especificado ...

Como o --rebase / --merge muda as coisas?

Meu principal caso de uso é ter um monte de repositórios centrais, que eu incorporarei via submódulos em outros repositórios. Eu gostaria de poder melhorar esses repositórios centrais, diretamente em sua localização original, ou de dentro de seus repositórios de incorporação (aqueles que os utilizam via submódulo).

  • De dentro desses submódulos, posso criar ramificações / modificações e usar push / pull como faria em repos regulares, ou existem coisas a serem cautelosas?
  • Como eu poderia avançar o submódulo referenciado commit de dizer (marcado) 1.0 para 1.1 (mesmo que o cabeçalho do repositório original já esteja em 2.0), ou escolher qual commit do branch é usado?

Esta página do GitPro resume a consequência de uma atualização do submódulo git bem

Quando você executa a git submodule update , ele verifica a versão específica do projeto, mas não dentro de uma ramificação. Isso é chamado de ter uma cabeça desanexada - significa que o arquivo HEAD aponta diretamente para uma confirmação, não para uma referência simbólica.
A questão é que você geralmente não quer trabalhar em um ambiente de cabeça isolada, porque é fácil perder as alterações .
Se você fizer uma atualização inicial do submódulo, confirme nesse diretório do submódulo sem criar uma ramificação para trabalhar e, em seguida, execute git submodule update novamente a partir do superprojeto sem confirmar, entretanto, o Git sobrescreverá suas alterações sem avisar você. Tecnicamente, você não perderá o trabalho, mas não terá uma ramificação apontando para ele, portanto, será um tanto difícil recuperá-lo.

Observe março de 2013:

Como mencionado em " git submodule tracking latest ", um submódulo agora (git1.8.2) pode rastrear uma ramificação.

# add submodule to track master branch
git submodule add -b master [URL to Git repo];

# update your submodule
git submodule update --remote 
# or (with rebase)
git submodule update --rebase --remote

Veja " git submodule update --remote vs git pull ".

A answer MindTooth ilustra uma atualização manual (sem configuração local):

git submodule -q foreach git pull -q origin master

Em ambos os casos, isso mudará as referências dos sub-módulos (o gitlink , uma entrada especial no índice repo pai ), e você precisará adicionar, confirmar e empurrar as referidas referências do repo principal.
Da próxima vez que você clonar esse repositório pai, ele preencherá os submódulos para refletir essas novas referências SHA1.

O restante desta resposta detalha o recurso de submódulo clássico (referência a um commit fixo , que é o ponto por trás da noção de um submódulo).

Para evitar esse problema, crie uma ramificação quando você trabalha em um diretório de sub-módulos com git checkout -b work ou algo equivalente. Quando você faz a atualização do submódulo pela segunda vez, ele ainda reverte seu trabalho, mas pelo menos você tem um ponteiro para voltar.

Alternar ramos com submódulos neles também pode ser complicado. Se você criar uma nova ramificação, incluir um submódulo nela e, em seguida, alternar de volta para uma ramificação sem esse submódulo, ainda terá o diretório do submódulo como um diretório não controlado:

Então, para responder suas perguntas:

posso criar ramificações / modificações e usar push / pull como faria em repos regulares, ou há coisas que devem ser cautelosas?

Você pode criar uma ramificação e enviar modificações.

ATENÇÃO (do Tutorial do Submódulo Git ): Sempre publique (push) a mudança do submódulo antes de publicar (push) a alteração no superprojeto que a referencia. Se você esquecer de publicar a alteração do submódulo, outras pessoas não poderão clonar o repositório.

Como eu poderia avançar o submódulo referenciado commit de dizer (marcado) 1.0 para 1.1 (mesmo que o chefe do repositório original já está em 2.0)

A página " Noções básicas sobre submódulos " pode ajudar

Os submódulos Git são implementados usando duas partes móveis:

  • o arquivo .gitmodules e
  • um tipo especial de objeto de árvore.

Estes juntos triangulam uma revisão específica de um repositório específico que é verificado em um local específico em seu projeto.

Da página do submodule git

você não pode modificar o conteúdo do submódulo de dentro do projeto principal

100% correto: você não pode modificar um submódulo, apenas se refira a um de seus commits.

É por isso que, quando você modifica um submódulo de dentro do projeto principal, você:

  • precisa se comprometer e empurrar dentro do submódulo (para o módulo upstream), e
  • então suba no seu projeto principal, e reconfigure (para que o projeto principal se refira ao novo submódulo commit recém-criado e enviado)

Um submódulo permite que você tenha um desenvolvimento de abordagem baseado em componentes , onde o projeto principal se refere apenas a commits específicos de outros componentes (aqui "outros repositórios Git declarados como sub-módulos").

Um submódulo é um marcador (commit) para outro repositório Git que não está vinculado ao ciclo de desenvolvimento do projeto principal: ele (o "outro" repositório do Git) pode evoluir de forma independente.
Cabe ao projeto principal escolher a partir desse outro repo qualquer que seja o seu compromisso.

No entanto, se você quiser, por conveniência , modificar um desses submódulos diretamente do seu projeto principal, o Git permite que você faça isso, desde que publique essas modificações no submódulo em seu repositório Git original e confirme seu projeto principal referindo-se a uma nova versão do dito submódulo.

Mas a idéia principal permanece: referenciando componentes específicos que:

  • tem seu próprio ciclo de vida
  • tem seu próprio conjunto de tags
  • tem seu próprio desenvolvimento

A lista de commits específicos aos quais você está se referindo em seu projeto principal define sua configuration (é sobre isso que trata o Configuration Management, englobando um mero Sistema de Controle de Versão )

Se um componente pudesse realmente ser desenvolvido ao mesmo tempo que seu projeto principal (porque qualquer modificação no projeto principal envolveria modificar o subdiretório, e vice-versa), então seria um "submódulo" não mais, mas um subtree merge (também apresentado na questão configuration ), ligando o histórico dos dois configuration Git juntos.

Isso ajuda a entender a verdadeira natureza dos Submodules do Git?


O Git 1.8.2 apresenta uma nova opção --remote que permitirá exatamente esse comportamento. Corrida

git submodule update --rebase --remote

irá buscar as últimas alterações do upstream em cada submódulo, rebase-as e confira a revisão mais recente do submódulo. Como os docs colocam:

--controlo remoto

Esta opção é válida apenas para o comando update. Em vez de usar o SHA-1 gravado do superprojeto para atualizar o submódulo, use o status da ramificação do controle remoto do submódulo.

Isso equivale a executar git pull em cada submódulo, que geralmente é exatamente o que você deseja.

(Copiado desta resposta )


Para endereçar a opção --rebase vs --merge:

Digamos que você tenha super-repo A e submódulo B e queira fazer algum trabalho no submódulo B. Você fez sua lição de casa e sabe que depois de chamar

git submodule update

você está em um estado sem CABEÇA, então qualquer commit que você fizer neste momento é difícil de voltar. Então, você começou a trabalhar em uma nova ramificação no submódulo B

cd B
git checkout -b bestIdeaForBEver
<do work>

Enquanto isso, outra pessoa no projeto A decidiu que a versão mais recente e melhor de B é realmente o que A merece. Você, por hábito, mescla as alterações mais recentes e atualiza seus submódulos.

<in A>
git merge develop
git submodule update

Oh não! Você está de volta em um estado sem cabeça novamente, provavelmente porque B agora está apontando para o SHA associado com a nova dica de B, ou algum outro commit. Se você tivesse:

git merge develop
git submodule update --rebase

Fast-forwarded bestIdeaForBEver to b798edfdsf1191f8b140ea325685c4da19a9d437.
Submodule path 'B': rebased into 'b798ecsdf71191f8b140ea325685c4da19a9d437'

Agora, a melhor ideia para B já foi rebaixada para o novo commit, e mais importante, você ainda está no seu ramo de desenvolvimento para B, não em um estado sem cabeça!

(o --merge irá mesclar as alterações de beforeUpdateSHA para afterUpdateSHA em sua ramificação de trabalho, em vez de redefinir suas alterações em afterUpdateSHA.)







git-submodules