Atualize um submódulo para a confirmação mais recente

269

Eu tenho um projeto A que é uma biblioteca e é usado em um projeto B.

Ambos os projetos A e B têm um repositório separado no github, mas dentro de B temos um submódulo de A.

Editei algumas classes na biblioteca, que está no repositório A, pressionei no repositório remoto, para que a biblioteca (repositório A) seja atualizada.

Essas atualizações não refletem na "referência" (o submódulo) que o submódulo refere-se a uma confirmação anterior .... o que devo fazer para atualizar o submódulo no git?

gordura
fonte

Respostas:

358

Digite o diretório do submódulo:

cd projB/projA

Puxe o repositório do seu projeto A ( não atualizará o status git do seu pai, projeto B):

git pull origin master

Volte para o diretório raiz e verifique a atualização:

cd ..
git status

Se o submódulo tiver sido atualizado antes, ele mostrará algo como abaixo:

# Not currently on any branch.
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#       modified:   projB/projA (new commits)
#

Em seguida, confirme a atualização:

git add projB/projA
git commit -m "projA submodule updated"

ATUALIZAR

Como o @paul apontou, desde o git 1.8, podemos usar

git submodule update --remote --merge

para atualizar o submódulo para a confirmação remota mais recente. Será conveniente na maioria dos casos.

Kjuly
fonte
35
BTW, se você não é o proprietário do submódulo, pode fazê-lo git submodule updatequando alguém atualizar o projA (você receberá um novo ID de confirmação).
Kjuly
Eu próprio o submodule repo principal (proj A), mas eu sou um committer na proj B.
gordura
@Kjuly Após o commit, como alguém o envia para o controle remoto? É só isso git push?
KR29
1
@ KR29 à direita e o cmd completo é git push <remote> <branch>, por exemplo git push origin dev.
Kjuly
2
git submodule updatesó funciona sem sinalizadores quando um commit foi puxado (no projeto B) que atualiza os refs para o (s) submódulo (s) em questão (projeto A). Para atualizar o projeto B para fazer referência à HEADramificação de rastreamento remoto do projeto A, faça o git submodule update --remote --mergeque é mostrado na resposta de Paul Hatcher abaixo.
Ben Burns,
109

Desde o git 1.8, você pode fazer

git submodule update --remote --merge

Isso atualizará o submódulo para a confirmação remota mais recente. Você precisará confirmar a alteração para que o gitlink no repositório pai seja atualizado

git commit

E, em seguida, forneça as alterações, sem isso, a identidade do SHA-1, apontando para o submódulo, não será atualizada e, portanto, a alteração não será visível para mais ninguém.

Paul Hatcher
fonte
Mesmo que eu faça git committodo mundo ainda não está vendo. On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: modified: SubmoduleA (new commits) modified: SubmoduleB (new commits)
Max
1
Você já fez um "git push" após a sua cometer, ter em mente cometer apenas muda seu repositório local, você tem que empurrá-lo para o controle remoto para todos os outros para vê-lo
Paul Hatcher
Faltando esta resposta (mas observada em outras respostas abaixo): o (s) submódulo (s) atualizado (s) precisa ser testado git addantes de confirmar.
joshng
1
@joshng Eu sinto que todos que estão no ponto em que estão trabalhando nos submódulos entenderiam isso. Este é o único post que me ajudou, muito obrigado.
Husk Rekoms
38

Se você atualizar um submódulo e se comprometer com ele, precisará ir para o repositório de nível contendo ou superior e adicionar a alteração lá.

git status

mostrará algo como:

modified:
   some/path/to/your/submodule

O fato de o submódulo estar fora de sincronia também pode ser visto com

git submodule

a saída mostrará:

+afafaffa232452362634243523 some/path/to/your/submodule

O sinal de mais indica que o submódulo está apontando para a frente onde o repositório superior espera que aponte.

basta adicionar esta alteração:

git add some/path/to/your/submodule

e comprometa-o:

git commit -m "referenced newer version of my submodule"

Ao empurrar suas alterações, certifique-se de empurrar a mudança no submódulo primeiro e depois empurre a alteração de referência no repositório externo. Dessa forma, as pessoas que atualizam sempre poderão executar com êxito

git submodule update

Mais informações sobre submódulos podem ser encontradas aqui http://progit.org/book/ch6-6.html .

Adam Dymitruk
fonte
Se você não vê +quando executa git submodule, verifique se inicializou e importou os submódulos. Os comandos para isso são git submodule inite git submodule update, respectivamente.
precisa saber é
19

Versão de linha única

git submodule foreach "(git checkout master; git pull; cd ..; git add '$path'; git commit -m 'Submodule Sync')"
Andy Webov
fonte
2

Algumas das outras respostas recomendam mesclar / confirmar no diretório do submódulo, que o IMO pode se tornar um pouco confuso.

Supondo que o servidor remoto seja nomeado origine desejemos a masterramificação do (s) submódulo (s), costumo usar:

git submodule foreach "git fetch && git reset --hard origin/master"

Nota: Isso fará uma redefinição definitiva em cada submódulo - se você não quiser, pode mudar --hardpara --soft.

XtraSimplicity
fonte
1

Meu projeto deve usar o 'mais recente' para o submódulo. No Mac OSX 10.11, git versão 2.7.1, eu não precisava entrar na minha pasta de submodule para coletar seus commits. Eu apenas fiz um regular

git pull --rebase 

no nível superior e atualizou corretamente meu submódulo.

AnneTheAgile
fonte
0

A resposta de Andy funcionou para mim escapando $ path:

git submodule foreach "(git checkout master; git pull; cd ..; git add \$path; git commit -m 'Submodule Sync')"
Miguel Fernandes Muldy
fonte
Provavelmente, a razão pela qual a resposta de @Andy Webov não exigiu escape foi porque eles usaram aspas simples no caminho, por exemplo. '$path'
S0AndS0