submódulo git não colocado em produção

Nov 26 2020

Acabei de criar um novo repositório com dois submódulos. Funciona bem no local, mas ao enviar para a produção os submódulos não estão lá. Cada diretório raiz do submódulo está presente, mas nenhum arquivo dentro

git version 2.27.0

Criar repo na produção

git --bare init
cd hooks && touch post-receive && chmod +x post-receive

cat hooks/post-receive
#/bin/sh
git --work-tree=/var/www/repo --git-dir=/var/git_repos/repo.git checkout -f

Enviando para produção a partir de dev / local

git push production master

git statusdiz que tudo está atualizado. Mesmo que seja chamado na pasta do submódulo. Tentei deletar a pasta do submódulo no repositório local, enviar / enviar para o repositório. Em seguida, git push production mastera pasta do submódulo raiz foi excluída do servidor de produção. Em seguida, tentando adicioná-lo novamente

# git submodule add [email protected]:alias/repo_name.git php/repo/repo_name
Cloning into '/var/www/project/php/repo/repo_name'...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (19/19), done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 19 (delta 8), reused 19 (delta 8), pack-reused 0
Receiving objects: 100% (19/19), 8.62 KiB | 8.62 MiB/s, done.
Resolving deltas: 100% (8/8), done.

Em seguida, comprometer-se com o repositório e então git push production master. O mesmo problema. Na produção, as pastas raiz dos submódulos estão presentes, mas não há arquivos nos diretórios.

Quando eu navego no repositório no github, os submódulos estão corretamente vinculados.

Tudo funciona no repositório local

Respostas

VonC Nov 28 2020 at 03:24

As pastas do submódulo não estão vazias no github (ou no repositório local), mas ao enviar para a produção elas estão

Isso é esperado: um submódulo é composto por:

  • um URL registrado no .gitmodules
  • a gitlink, uma entrada especial no índice que representa o SHA1 da árvore raiz do repositório de submódulo.

Quando você clona um repositório remoto com submódulos (usando a git clone --recurse-submodulesopção, esses repositórios de submódulo são clonados e retirados no SHA1 representado por aquele gitlink.

"Enviar para produção" é complicado porque você não deve enviar para um repositório retirado (não vazio) (mesmo que você possa fazê-lo tecnicamente ).

É melhor enviar para um repositório vazio na produção, que usará um gancho pós-recebimento para restaurar os arquivos (incluindo o conteúdo do submódulo, usando git restore --recurse-submodules)


Após discussão :

  1. Você precisa que o servidor de produção tenha uma chave SSH pública registrada em sua conta, uma vez que os submódulos são registrados no .gitmodulescom um URL SSH.

  2. O script pós-recebimento torna-se:

    #!/bin/bash
    cd /var/www/repo
    git --git-dir=/var/git_repos/repo.git --work-tree=. restore --recurse-submodules :/
    

Com git submodule, você não pode definir a árvore de trabalho aparentemente

Isso significa que, se houver submódulos envolvidos, sua pasta atual deve ser a árvore de trabalho.

Então você pode fazer comandos como git checkout/ git restorecom --recurse-submodules, ou git submodule update --init, até mesmo com um git-dir ( --git-dir=/path/to/bare/repo.git) diferente.

Os submódulos serão atualizados porque sua árvore de trabalho atual é a correta.

Se você estiver em qualquer lugar que não seja /var/www/repo, mesmo que especifique git --work-tree=/var/www/repo ..., nenhum dos comandos mencionados acima git checkout/ git restorecom --recurse-submodules, ou git submodule update --initfuncionará para os submódulos do seu repo.
Ou seja: Seus /var/www/repoarquivos serão restaurados, mas os submódulos permanecerão vazios.