Git não irá inicializar / sincronizar / atualizar novos submódulos

113

Aqui está parte do conteúdo do meu .gitmodulesarquivo:

[submodule "src/static_management"]
        path = src/static_management
        url = git://github.com/eykd/django-static-management.git
[submodule "external/pyfacebook"]
        path = external/pyfacebook
        url = http://github.com/sciyoshi/pyfacebook.git

No entanto, .git/configcontém apenas o primeiro:

[submodule "src/static_management"]
        url = git://github.com/eykd/django-static-management.git

O segundo submódulo ( external/pyfacebook) foi adicionado por outro desenvolvedor em um branch de recurso. Eu herdei o desenvolvimento agora e verifiquei o branch de recursos. No entanto, o Git não puxará o submódulo para mim. Eu tentei:

  • git submodule init
  • git submodule update
  • git submodule update --init
  • git submodule sync
  • Removendo todas as definições de submódulo .git/confige em execução git submodule init. Ele apenas copia o submódulo existente anteriormente e ignora o novo.
  • Inserindo novas definições de submódulo .git/configmanualmente e em execução git submodule update. Apenas os submódulos existentes anteriormente se preocupam em atualizar.

em várias combinações, mas o git simplesmente não atualizará com .git/configbase no novo conteúdo de .gitmodules, nem criará a external/pyfacebookpasta e extrairá o conteúdo do submódulo.

o que estou perdendo? A intervenção manual (adicionar uma entrada de submódulo manualmente .git/config) é realmente necessária e por quê?

Editar: a intervenção manual não funciona. Adicionar manualmente a nova entrada de submódulo .git/confignão faz nada. O novo submódulo é ignorado.

David Eyk
fonte
1
executando 1.7.7.1 e tendo o mesmo problema: "git submodule sync" não atualiza .git / config após uma mudança para .gitmodules.
James Pritts

Respostas:

35

Você atualizou recentemente para o git versão 1.7.0.4? Eu fiz e agora estou tendo problemas semelhantes ...

Edit: Corrigi meu problema, mas não tenho absolutamente nenhuma ideia de onde estava o problema. Eu removi manualmente as entradas de submódulo de ambos .git / config e .gitmodules e re-adicionei meus submódulos com as etapas usuais (git submodule add etc ...) ... Worksforme mas não adiciona nenhum valor a este tópico.

Quickredfox
fonte
Estou até 1.7.2 agora, mas acredito que tenho tido o problema desde pelo menos 1.6.x.
David Eyk
E sim, pensando bem, acabei tendo que fazer o que você descreve (esqueci que essa questão ainda estava em aberto!). Se você não se importar em polir um pouco sua resposta, eu aceitarei.
David Eyk
9
Esta é uma fraqueza contínua do git. Até mesmo o svn é melhor com externos.
Peter DeWeese
3
Acho que acabei de encontrar isso também (as mesmas etapas parecem finalmente consertar). A única coisa que notei é que, depois de adicioná-lo novamente, em seguida, confirmar, o commit disse: modo de criação 160000 lib / jruby-swing-helpers (hein?)
rogerdpack
1
Sobre o "modo de criação 160000", o livro Pro Git diz o seguinte: "Observe o modo 160000 para a entrada do rack. Esse é um modo especial no Git que basicamente significa que você está gravando um commit como uma entrada de diretório em vez de um subdiretório ou um Arquivo." git-scm.com/book/en/Git-Tools-Submodules
Johann
92

Eu tive o mesmo problema - descobriu-se que o arquivo .gitmodules foi confirmado, mas o commit do submódulo real (ou seja, o registro do ID de commit do submódulo) não.

Adicioná-lo manualmente parecia funcionar - por exemplo:

git submodule add http://github.com/sciyoshi/pyfacebook.git external/pyfacebook

(Mesmo sem remover nada de .git / config ou .gitmodules.)

Em seguida, comprometa-o para registrar o ID corretamente.

Adicionando mais alguns comentários a esta resposta de trabalho: Se o submódulo git init ou atualização do submódulo git não funcionar, então, como descrito acima, o submódulo git add url deve resolver. Pode-se verificar isso por

 git config --list

e deve-se obter uma entrada do submódulo que você deseja obter no resultado do comando git config --list. Se houver uma entrada de seu submódulo no resultado da configuração, agora o submódulo git usual update --init deve puxar seu submódulo. Para testar esta etapa, você pode renomear manualmente o submódulo e atualizá-lo.

 mv yourmodulename yourmodulename-temp
 git submodule update --init

Para descobrir se você tem mudanças locais no submódulo, pode ser visto via git status -u (se você quiser ver as mudanças no submódulo) ou git status --ignore-submodules (se você não quiser ver as mudanças no o submódulo).

Dave James Miller
fonte
Para que serve external/pyfacebook?
IgorGanapolsky
2
@IgorGanapolsky Esse é o caminho de destino para seu submódulo.
yuhua
Isso me ajudou, muito obrigado! Eu poderia apenas acrescentar que se o caminho de destino já existe (o que aconteceu para mim como resultado da tentativa de outros comandos), obtém-se a seguinte mensagem, que só aumenta a confusão:'your/local/path' already exists and is not a valid git repo
Michael Ambrus
1
uma linha para ler as entradas em "git config --list":git config --list | grep submodule | sed -e "s/submodule\.//" -e "s/\(.*\)\.url=\(.*\)/git submodule add --force \2 \1/" | bash
Puggan Se
64

git versão 2.7.4. Este comando atualiza o código local git submodule update --init --force --remote

palik
fonte
20
Não fazendo nada por mim.
Carlo Wood
1
no que diz respeito ao git-submodule [documentação) ( git-scm.com/docs/git-submodule#git-submodule---remote ), o comando mencionado acima deve atualizar o branch local dos submódulos.
palik
1
@palik você é demais!
Denis Trofimov
1
Você pode atualizar o módulo individual com git submodule update --init --force --remote <module-name>.
Adam Faryna
15

Tive o mesmo problema, quando git ignorou inite updatecomanda, e não faz nada.

COMO CONSERTAR

  1. Sua pasta de submódulo deve ser confirmada no repo git
  2. Não deveria estar em .gitignore

Se esses requisitos forem atendidos, funcionará. Caso contrário, todos os comandos serão executados sem nenhuma mensagem e resultado.

Se você fez tudo isso, e ainda assim não funcionar:

  1. Adicione o submódulo manualmente, por exemplo git submodule add git@... path/to
  2. git submodule init
  3. git submodule update
  4. confirmar e enviar todos os arquivos - .gitmodulese sua pasta de módulo (observe que o conteúdo da pasta não será confirmado)
  5. largue seu repositório git local
  6. clonar um novo
  7. certifique-se de que .git/configainda não tem submódulos
  8. Agora, git submodule init- e você verá uma mensagem que o módulo registrou
  9. git submodule update - irá buscar o módulo
  10. Agora olhe para .git/confige você encontrará o submódulo registrado
Alex Ivasyuv
fonte
1
Acredito que o caminho para os submódulos PODE ser em .gitignore. Pelo menos fiz funcionar seguindo a resposta de @DaveJamesMiller. Nada mais funcionou para mim.
gebbissimo
7

Parece haver muita confusão aqui (também) nas respostas.

git submodule inité não pretende gerar magicamente coisas em .git / config (de .gitmodules). A intenção é configurar algo em um subdiretório totalmente vazio após clonar o projeto pai ou puxar um commit que adiciona um submódulo não existente anteriormente.

Em outras palavras, você segue a git clonede um projeto que tem submódulos (que você saberá pelo fato de que o clone fez check-out de um arquivo .gitmodules) por a git submodule update --init --recursive.

Você não segue git submodule add ...com um git submodule init(ou git submodule update --init), isso não deveria funcionar. Na verdade, o add já atualizará o .git / config apropriado se as coisas funcionarem.

EDITAR

Se um submódulo git não existente anteriormente foi adicionado por outra pessoa, e você fizer um git pulldesse commit, então o diretório desse submódulo estará inteiramente vazio (quando você executar git submodule statuso novo hash do submódulo deve estar visível, mas terá um -na frente de .) Nesse caso, você precisa seguir seu git pulltambém com um git submodule update --init(mais --recursivequando é um submódulo dentro de um submódulo) para fazer o check-out do novo submódulo, anteriormente não existente; assim como após um clone inicial de um projeto com submódulos (onde obviamente você não tinha esses submódulos antes também).

Carlo madeira
fonte
1
Isso é interessante, porque git help submodulediz o seguinte sobre o init: "init: inicializa os submódulos registrados no índice (que foram adicionados e confirmados em outro lugar) copiando os nomes e urls dos submódulos de .gitmodules para .git / config." Então com certeza parece que ele deve fazer exatamente o que você diz que não faz ...? É hora de atualizar a documentação do git?
Brad
@brad Acho que não disse isso - mas acrescentei um esclarecimento para esse caso específico. Obrigado.
Carlo Wood
@CarloWood alguma ideia de por que os escritores de submódulos git decidiram que --initdeveria ser necessário obter novos submódulos (em vez de capturá-los automaticamente update)? Parece que atualizar seu repositório deve pegar tudo o que é necessário, a menos que destrua dados. Com --initele o força a saber que novos submódulos podem ter sido criados, ou apenas sempre emitir um a --initcada vez, caso em que, novamente, parece que ele deve ser habilitado por padrão.
Catskul 01 de
@Catskul Obviamente, não tenho ideia de por que os escritores dos submódulos git decidiram alguma coisa, mas meu palpite é que "update" é reservado para atualizar algo que já existe e "init" é usado para criar algo (localmente) novo. Sob o capô, os dois são provavelmente significativamente diferentes o suficiente para justificar um comando diferente.
Carlo Wood
6

Eu tive o mesmo problema, mas nenhuma das soluções acima ajudou. As entradas nos módulos .git e .git / config estavam corretas, mas o comando git submodules update --init --recursivenão fazia nada. Eu também removi o diretório do submódulo e executei git submodules update --init --recursivee recebi o diretório do submódulo de volta, mas com exatamente o mesmo commit de antes.

Eu encontrei a resposta nesta página . O comando é:git submodule update --remote

mestre
fonte
2
Essa também foi a solução correta para mim. Eu estava correndo em git submodule updatevez de git submodule update --remote.
Andrew Medlin
5

Meio que magicamente, mas hoje eu corri git submodule initseguido por git submodule syncseguido de git submodule updatee começou a puxar meus submódulos ... Mágica? Possivelmente! Esta é realmente uma das experiências mais irritantes com Git ...

Risca isso. Eu realmente consegui fazer isso funcionar git submodule update --init --recursive. Espero que isto ajude.

PS: Certifique-se de estar no diretório raiz do git, não no submódulo.

Levi Figueira
fonte
7
Nah, isso não faz absolutamente nada para mim.
IgorGanapolsky
@IgorGanapolsky Editei a resposta acima com o que funcionou para mim. Deixe-me saber se funciona!
Levi Figueira
Tentei seus novos comandos, mas eles também não fizeram nada.
IgorGanapolsky
5

Pensar que configurar manualmente .gitmodulesé o suficiente é ERRADO

Meu local no git version 2.22.0momento desta escrita.

Então cheguei a este tópico perguntando por que não estava git submodule initfuncionando; Eu configurei o .gitmodulesarquivo e continuei a fazer git submodule init...

IMPORTANTE

  1. git submodule add company/project.git includes/projecté necessário (ao adicionar o módulo pela primeira vez), isso irá:

    • adicionar configuração a .git/config
    • atualize o .gitmodulesarquivo
    • rastrear a localização do submódulo ( includes/projectneste exemplo).
  2. você deve então, git commitdepois de adicionar o submódulo, ele irá confirmar .gitmodulese a localização do submódulo rastreado.

Quando o projeto for clonado novamente, ele terá o .gitmodulesdiretório de submódulos e vazio (por includes/projectexemplo, neste exemplo). Neste ponto, .git/configainda não há configuração de submódulo, até que git submodule initseja executado, e lembre-se de que isso só funciona porque .gitmodulesAND includes/projectsão rastreados no repositório git principal.

Também para referência, consulte:

farinspace
fonte
3

Eu tive o mesmo problema.

.gitmodulesteve o sub-módulo, mas depois de um git submodule initcomando que não estava em .git/config.

Acontece que o desenvolvedor que adicionou o submódulo também adicionou o diretório do submódulo ao .gitignorearquivo. Isso não funciona.

joseph.hainline
fonte
2

Da mesma forma que você, descobri que git submodule sync não faz o que você espera. Somente depois de fazer um explícito git submodule addnovamente é que uma URL de submódulo muda.

Então, coloquei este script em ~/bin/git-submodule-sync.rb:

https://gist.github.com/frimik/5125436

E também uso a mesma lógica em alguns scripts git deploy pós-recebimento.

Tudo o que preciso fazer agora é editar .gitmodules, executar este script e ele finalmente funcionará como pensei que git submodule syncdeveria.

fridh
fonte
Isso parece acontecer apenas em alguns repositórios ... possivelmente devido a algum bug no Git. Faz muito tempo que não acontecia comigo em repositórios recém- criados, mas, no passado, acontecia o tempo todo em certos
repositórios
2

Eu tive o mesmo problema hoje e descobri isso porque eu digitei git submodule inite tinha essas linhas no meu .git/config:

[submodule]
   active = .

Eu removi isso e digitei:

git submodule update --init --remote

E tudo voltou ao normal, meu submódulo atualizado em seu subdiretório como de costume.

Eric Jeker
fonte
2

O problema para mim é que o desenvolvedor anterior do repo comprometeu a submodules/thingpasta como uma pasta normal, o que significa que quando eu tentei executar git submodule add ..., ela falhou com:, 'submodules/thing' already exists in the indexmas tentar atualizar o submódulo também falhou porque viu que o caminho não contém um submódulo.

Para corrigir, eu tive que excluir a submodules/thingpasta, confirmar a exclusão e executar o git submodule addcomando para adicioná-la de volta corretamente:

git submodule add --force --name thing https://github.com/person/thing.git submodules/thing
Venryx
fonte
1

Quando eu vi isso hoje, um desenvolvedor moveu parte da árvore para um novo subdiretório e parece que seu cliente git não gravou as regras atualizadas do subprojeto na árvore, em vez disso, elas foram apenas nukadas, deixando .gitmodulesambos como obsoletos locais e subprojetos que não existiam mais na árvore atual.

Adicionando os submódulos de volta e comparando os commit shas do submódulo com aqueles encontrados em git show $breaking_commit_sha(procure por linhas que correspondam ao regexp ^-Subproject) para ajustar conforme necessário, coisas fixas.

Phil P
fonte
1

Excluir o diretório de submódulo e seu conteúdo (pasta "external / pyfacebook") se ele existir antes git submodule add ...pode resolver os problemas.

atahan
fonte
1
Esse foi o meu problema. Alguém comprometeu a pasta "submodule" como uma pasta normal, o que significa que quando eu tentei executar "git submodule add ...", ela falharia com: "'vendor / mobx-state-tree' já existe no índice" , ainda que tentar atualizar o submódulo também falhará porque viu que o caminho não continha um submódulo). Para corrigir, eu tive que excluir a pasta, confirmar a exclusão e executar o comando git add para adicioná-la de volta corretamente.
Venryx
1

Tive um problema semelhante com um submódulo. Ele só não queria ser clonado / puxado / atualizado / qualquer coisa.

Ao tentar adicionar novamente o submódulo usando git submodule add [email protected] destination, obtive a seguinte saída:

A git directory for 'destination' is found locally with remote(s):
  origin        [email protected]
If you want to reuse this local git directory instead of cloning again from
  [email protected]
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

Portanto, tentei aplicar o comando add :
git submodule add --force [email protected] destination

Isso funcionou no meu caso.

Arvid
fonte
0

Para registro:
eu criei o mesmo problema adicionando um repositório vazio como submódulo. Nesse caso, não havia hash de referência disponível para o submódulo, levando ao erro descrito pelo autor original.

A adição forçada do repositório após ter se comprometido com ele resolveu o problema (como na postagem do Arvids)
git submodule add --force [email protected] destination

Marc
fonte
0
  • Remova o submódulo de seu .git/config
  • Executar git submodule initcomando
  • Vá para o diretório do seu submódulo e execute git pull origin master

Deve funcionar agora

Masoud Darvishian
fonte
0

Apenas compartilhando o que funcionou para mim:

git clone --recurse-submodules <repository path>

Isso clona o repositório remoto já incluindo os submódulos. Isso significa que você não precisará executar git submodule update ou init após a clonagem.

Anne Kariny Silva Freitas
fonte
0

O comando de sincronização abaixo resolveu o problema:

git submodule sync
Nishant Chauhan
fonte