Existe-t-il un moyen pour que git pull mette automatiquement à jour les sous-modules?

203

Existe-t-il un moyen d'avoir automatiquement git submodule update(ou de préférence git submodule update --initappelé chaque fois que git pullc'est fait?

Vous recherchez un paramètre de configuration git ou un alias git pour vous aider.

philfreo
la source
1
Pourquoi un alias git est-il préférable à un alias shell?
wnoise
20
Les alias git sont agréables car ils encapsulent la commande dans l'espace de noms "git". Vous pouvez aussi demander pourquoi toutes les commandes git commencent par "git" au lieu d'avoir leurs propres noms.
Lily Ballard du
5
Pour tous ceux qui trouvent cela, les réponses les plus votées sont actuellement obsolètes. La réponse de Kane est exacte: stackoverflow.com/a/49427199/3499424
John Neuhaus

Réponses:

176

Depuis Git 2.14 , vous pouvez l'utiliser git pull --recurse-submodules(et l'aliaser comme bon vous semble).

Depuis Git 2.15 , vous pouvez définir submodule.recursetrue pour activer le comportement souhaité.

Vous pouvez le faire globalement en exécutant:

git config --global submodule.recurse true
Kane
la source
3
Confirmé avec 2.16, le définir sur true entraînera git pullégalement la récupération d'un sous-module et son exécution submodule update. Cela doit vraiment être la réponse acceptée maintenant
John Neuhaus
1
Pour définir cela globalement:git config --global submodule.recurse true
wintersolutions
14
J'étais frustré par les sous-modules, puis je l'ai fait. Maintenant, ils fonctionnent comme je m'y attendais. Y a-t-il une raison pour laquelle je ne pense pas que ce n'est pas le comportement par défaut?
Ben
9
Ils devraient également permettre cela git clone. Et activez-le par défaut. Sinon, il y aura toujours une énorme résistance à l'utilisation des sous-modules, car les modules des gens seront toujours désynchronisés :-(
Ciro Santilli 30 冠状 病 六四 事件 法轮功
1
@CiroSantilli新疆改造中心法轮功六四事件Santilli commandes git (comme commit, fetch, pull, etc.) sont conçus pour être appliqués que dans le référentiel courant. un sous-module est un autre référentiel et ne devrait pas être affecté par les commandes exécutées dans le référentiel parent par défaut. c'est une sorte de décision de conception par le développeur git.
anion
113

git config --global alias.pullall '!git pull && git submodule update --init --recursive'

Si vous voulez que des arguments soient passés à git pull, utilisez plutôt ceci:

git config --global alias.pullall '!f(){ git pull "$@" && git submodule update --init --recursive; }; f'
Lily Ballard
la source
4
n'oubliez pas d'utiliser "git config --global" si vous voulez cet alias sur tous les dépôts git que vous utilisez
yoyo
43

À partir de Git 1.7.5, il devrait mettre à jour les sous-modules automatiquement par défaut comme vous le souhaitez.

[EDIT: par commentaires: le nouveau comportement 1.7.5 consiste à récupérer automatiquement les derniers commits des sous-modules, mais pas à les mettre à jour (dans le git submodule updatesens). Les informations contenues dans cette réponse sont donc pertinentes en tant que contexte, mais ne sont pas une réponse complète en soi. Vous avez toujours besoin d'un alias pour extraire et mettre à jour des sous-modules en une seule commande.]

Le comportement par défaut, "à la demande", consiste à mettre à jour les sous-modules chaque fois que vous récupérez une validation qui met à jour la validation du sous-module, et cette validation ne se trouve pas déjà dans votre clone local.
Vous pouvez également le mettre à jour à chaque extraction ou jamais (comportement antérieur à la 1.7.5 je suppose).
L'option de configuration pour modifier ce comportement est fetch.recurseSubmodules.

Cette option peut être définie sur une valeur booléenne ou sur on-demand.
Le paramétrer sur un booléen change le comportement de fetchet pullde reconditionner inconditionnellement en sous-modules lorsqu'il est défini sur true ou de ne pas récurser du tout lorsqu'il est défini sur false.

Lorsqu'il est défini sur on-demand(la valeur par défaut), fetchet pull ne récursive dans un sous-module rempli que lorsque son superprojet récupère un commit qui met à jour la référence du sous-module .

Voir:

pour plus d'informations.

git fetch --recurse-submodules[=yes|on-demand|no]
Christopher Rogers
la source
27
Attention: comme l'expliquent les réponses ci-dessous, cela ne récupère que les modifications automatiquement, vous devez toujours faire une mise à jour du sous-module - donc la réponse d'alias est correcte.
Artem
4
@Artem est correct. Cette réponse, bien qu'utile, ne répond pas à toute la question. Ce paramètre exécute simplement un git fetch, pas un git submodule update.
Andrew Ferrier
2
Cette réponse est très trompeuse. Même lorsqu'elle est utilisée avec git pull, plutôt que git fetch, cette option rend uniquement la récupération récursive. Cela ne changera pas du tout quel commit est extrait dans les sous-modules. Il git submodule updateest donc toujours nécessaire, comme l'a noté @Artem.
Mark Amery
31

Je suis surpris que personne n'ait mentionné utiliser de git hooks pour ce faire!

Ajoutez simplement les fichiers nommés post-checkoutet post-mergeà votre .git/hooksrépertoire des référentiels pertinents, et mettez les éléments suivants dans chacun d'eux:

#!/bin/sh
git submodule update --init --recursive

Puisque vous avez spécifiquement demandé un alias, en supposant que vous souhaitiez l'avoir pour de nombreux référentiels, vous pouvez créer un alias qui les ajoute à un référentiel .git/hookspour vous.

taleinat
la source
2
Existe-t-il un moyen d'en faire un cadre mondial? Ou celui que vous obtenez automatiquement lors de la vérification du référentiel?
Raoul Steffen
3
La dernière version de git, 2.9, a ajouté un paramètre nommé core.hooksPathpour un répertoire hooks , consultez la documentation git-configpour plus de détails.
taleinat
1
Quant à quelque chose reçu automatiquement lors de la vérification, j'ai cherché mais je n'ai rien trouvé de tel. Une source a mentionné que cela n'est pas délibérément pris en charge pour les problèmes de sécurité, car il pourrait assez facilement être utilisé pour exécuter du code arbitraire sur les ordinateurs clients.
taleinat
1
Je vois comment cela peut être un problème de sécurité. Après tout, je veux l'utiliser pour exécuter le code que je programme sur les ordinateurs de mes collègues sans avoir à les instruire.
Raoul Steffen
1
Cette solution a été ma première pensée, mais j'ai réalisé qu'elle ne couvrirait pas les personnes qui utilisent git pull --rebase:(
Vaz
8

Un pseudonyme, comme l'a suggéré Kevin Ballard, est une très bonne solution. Juste pour lancer une autre option, vous pouvez également utiliser un hook post-fusion qui s'exécute simplement git submodule update [--init].

Cascabel
la source
7

Vous pouvez créer un alias pour la commande git qui gère automatiquement la mise à jour des sous-modules. Ajoutez ce qui suit à votre .bashrc

# make git submodules usable
#   This overwrites the 'git' command with modifications where necessary, and
#   calls the original otherwise
git() {
    if [[ $@ == clone* ]]; then
        gitargs=$(echo "$@" | cut -c6-)
        command git clone --recursive $gitargs
    elif [[ $@ == pull* ]]; then
        command git "$@" && git submodule update --init --recursive
    elif [[ $@ == checkout* ]]; then
        command git "$@" && git submodule update --init --recursive
    else
        command git "$@"
    fi
}
Branden Ghena
la source
1
Au lieu d'un alias pour git, vous pouvez ajouter des alias à git via la commande alias ou en créant des commandes dans votre chemin commençant par git- (git-bettermodule)
idbrii
7

Comme d'autres l'ont mentionné, vous pouvez facilement régler cela avec:

git config --global submodule.recurse true

Cependant, si vous êtes comme moi et avez une .gitconfigconfiguration plus complexe (mon ~/.gitconfigfichier principal utilise includepour charger dans d'autres .gitconfigfichiers), et vous ne vous souvenez jamais comment convertir entre le gitformat de configuration de ligne de commande et le .gitconfigformat, voici comment l'ajouter à l'un de vos .gitconfigfichiers:

[submodule]
  recurse = true
JacobEvelyn
la source
0

La seule façon dont j'ai pu mettre à jour les sous-modules et les sous-modules imbriqués:

git submodule update --remote --merge --recursive; git submodule foreach --recursive "(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);" git add .; git commit -m 'SubmodulesSynced'; git push; git pull;

J'avais du mal à créer l'alias via le terminal en raison des crochets, j'ai donc dû l'ajouter manuellement à .gitconfig pour global:

[alias] supdate = "!git submodule update --remote --merge --recursive; git submodule foreach --recursive '(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);' git add .; git commit -m 'SubmodulesSynced'; git push; git pull;"

Des suggestions sur la façon d'exécuter les commandes ou l'alias automatiquement?

Sauli Kiviranta
la source