sous-module git non poussé en production

Nov 26 2020

Je viens de créer un nouveau référentiel avec deux sous-modules. Cela fonctionne bien en local, mais lors de la mise en production, les sous-modules ne sont pas là. Chaque répertoire racine de sous-module est présent, mais aucun fichier à l'intérieur

git version 2.27.0

Créer un repo en production

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

Pousser vers la production depuis le développement / local

git push production master

git statusdit que tout est à jour. Même s'il est appelé dans le dossier du sous-module. J'ai essayé de supprimer le dossier du sous-module sur le référentiel local, validez / poussez vers le référentiel. Ensuite git push production master, le dossier du sous-module racine a été supprimé sur le serveur de production. Puis en essayant de l'ajouter à nouveau

# 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.

Puis s'engager dans le référentiel et ensuite git push production master. Le même problème. En production, les dossiers racine des sous-modules sont présents mais aucun fichier dans les répertoires.

Lorsque je parcours le référentiel sur github, les sous-modules sont correctement liés.

Tout fonctionne dans le référentiel local

Réponses

VonC Nov 28 2020 at 03:24

Les dossiers de sous-modules ne sont pas vides sur github (ou dans le dépôt local), mais lors de la mise en production, ils sont

Cela est attendu: un sous-module est composé de:

  • une URL enregistrée dans le .gitmodules
  • a gitlink, une entrée spéciale dans l'index qui représente le SHA1 de l'arborescence racine du référentiel de sous-modules.

Lorsque vous clonez un référentiel distant avec des sous-modules (en utilisant l' git clone --recurse-submodulesoption, ces référentiels de sous-modules sont eux-mêmes clonés et extraits au SHA1 représenté par ce gitlink.

"Pousser vers la production" est délicat parce que vous n'êtes pas censé pousser vers un référentiel extrait (non nu) (même si vous pouvez le faire techniquement ).

Il est préférable de pousser vers un référentiel nu en production, qui utilisera un hook post-réception pour restaurer les fichiers (y compris le contenu du sous-module, en utilisant git restore --recurse-submodules)


Après discussion :

  1. Le serveur de production doit avoir une clé SSH publique enregistrée sur votre compte, car les sous-modules sont enregistrés dans le .gitmodulesavec une URL SSH.

  2. Le script de post-réception devient:

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

Avec git submodule, vous ne pouvez pas définir l'arborescence de travail apparemment

Cela signifie que si des sous-modules sont impliqués, votre dossier actuel doit être l'arborescence de travail.

Ensuite, vous pouvez faire des commandes comme git checkout/ git restoreavec --recurse-submodules, ou git submodule update --init, même avec un autre git-dir ( --git-dir=/path/to/bare/repo.git).

Les sous-modules seront mis à jour car votre arbre de travail actuel est le bon.

Si vous êtes n'importe où /var/www/repo, même si vous spécifiez git --work-tree=/var/www/repo ..., aucune des commandes susmentionnées git checkout/ git restoreavec --recurse-submodules, ou git submodule update --initfonctionnera pour les sous-modules de votre dépôt.
Autrement dit: vos /var/www/repofichiers seront restaurés, mais les sous-modules resteront vides.