web-dev-qa-db-fra.com

Un moyen facile d'extraire le dernier de tous les sous-modules git

Nous utilisons des sous-modules git pour gérer deux grands projets qui dépendent de nombreuses autres bibliothèques que nous avons développées. Chaque bibliothèque est un rapport séparé introduit dans le projet dépendant en tant que sous-module. Pendant le développement, nous souhaitons souvent simplement récupérer la dernière version de chaque sous-module dépendant.

Est-ce que git a une commande intégrée pour le faire? Sinon, que diriez-vous d'un fichier de commandes Windows ou d'un fichier similaire capable de le faire?

1535
Brad Robinson

Pour git 1.8.2 ou supérieur, l'option --remote a été ajoutée pour prendre en charge la mise à jour des derniers conseils des branches distantes:

git submodule update --recursive --remote

Cela présente l’avantage supplémentaire de respecter les branches "non définies par défaut" spécifiées dans les fichiers .gitmodules ou .git/config (le cas échéant, le paramètre par défaut est Origine/maître, auquel cas certaines des autres réponses ici fonctionneraient également).

Pour git 1.7.3 ou une version ultérieure, vous pouvez utiliser (mais la description ci-dessous ne permet pas de déterminer quelle mise à jour s'applique toujours):

git submodule update --recursive

ou:

git pull --recurse-submodules

si vous voulez tirer vos sous-modules vers les derniers commits, indiquez ce que le repo indique.

Remarque: Si c’est la première fois que vous extrayez un dépôt, vous devez d’abord utiliser --init:

git submodule update --init --recursive

Pour plus ancien, git 1.6.1 ou supérieur, vous pouvez utiliser quelque chose de similaire à (modifié en conséquence):

git submodule foreach git pull Origin master

Voir sous-module git (1) pour plus de détails

2012
Henrik Gustafsson

Si vous devez extraire des éléments pour les sous-modules dans vos référentiels de sous-modules, utilisez

git pull --recurse-submodules

une fonctionnalité que Git a apprise pour la première fois en 1.7.3.

Mais cela ne vérifiera pas les commits appropriés (ceux sur lesquels votre référentiel maître pointe) dans les sous-modules

Pour valider les commits appropriés dans vos sous-modules, vous devez les mettre à jour après avoir extrait en utilisant

git submodule update --recursive --remote
584
Alexander Bartosh

Sur init, exécutez la commande suivante:

git submodule update --init --recursive

depuis le répertoire git repo, me convient le mieux.

Cela va tirer tous les derniers, y compris les sous-modules.

A expliqué

git - the base command to perform any git command
    submodule - Inspects, updates and manages submodules.
        update - Update the registered submodules to match what the superproject
        expects by cloning missing submodules and updating the working tree of the
        submodules. The "updating" can be done in several ways depending on command
        line options and the value of submodule.<name>.update configuration variable.
            --init without the explicit init step if you do not intend to customize
            any submodule locations.
            --recursive is specified, this command will recurse into the registered
            submodules, and update any nested submodules within.

Après cela, vous pouvez simplement lancer:

git submodule update --recursive

depuis le répertoire git repo, me convient le mieux.

Cela va tirer tous les derniers, y compris les sous-modules.

A expliqué

git - the base command to perform any git command
    submodule - Inspects, updates and manages submodules.
        update - Update the registered submodules to match what the superproject
        expects by cloning missing submodules and updating the working tree of the
        submodules. The "updating" can be done in several ways depending on command
        line options and the value of submodule.<name>.update configuration variable.
            any submodule locations.
            --recursive is specified, this command will recurse into the registered
            submodules, and update any nested submodules within.
341
abc123

Note: Ceci est de 2009 et peut avoir été bon alors mais il y a de meilleures options maintenant.

Nous utilisons ceci. Il s'appelle git-pup:

#!/bin/bash
# Exists to fully update the git repo that you are sitting in...

git pull && git submodule init && git submodule update && git submodule status

Il suffit de le placer dans un répertoire bin approprié (/ usr/local/bin). Si vous utilisez Windows, vous devrez peut-être modifier la syntaxe pour que cela fonctionne :)

Mettre à jour:

En réponse au commentaire de l’auteur original sur l’inclusion de tous les HEAD de tous les sous-modules, c’est une bonne question.

Je suis à peu près sûr que git n'a pas de commande pour cela en interne. Pour ce faire, vous devez identifier ce que HEAD représente réellement pour un sous-module. Cela pourrait être aussi simple que de dire que master est la branche la plus récente, etc ...

Ensuite, créez un script simple qui effectue les opérations suivantes:

  1. vérifiez git submodule status pour les référentiels "modifiés". Le premier caractère des lignes de sortie l'indique. Si un sous-dépôt est modifié, vous ne voudrez peut-être PAS continuer.
  2. pour chaque repo répertorié, insérez cd dans son répertoire et lancez git checkout master && git pull. Vérifier les erreurs.
  3. À la fin, je vous suggère d’imprimer un écran à l’utilisateur pour indiquer l’état actuel des sous-modules - peut-être Invitez-les à tout ajouter et à valider?

Je voudrais mentionner que ce style n’est pas vraiment ce pour quoi les sous-modules git ont été conçus. En règle générale, vous voulez dire que "LibraryX" est à la version "2.32" et le restera jusqu'à ce que je lui dise de "mettre à niveau".

En un sens, c’est ce que vous faites avec le script décrit, mais plus automatiquement. Les soins sont nécessaires!

Mise à jour 2:

Si vous êtes sur une plate-forme Windows, vous pouvez envisager d’utiliser Python pour implémenter le script car il est très capable dans ces domaines. Si vous êtes sur unix/linux, alors je vous suggère juste un script bash.

Besoin de précisions? Il suffit de poster un commentaire.

301
gahooa

Henrik est sur la bonne voie. La commande 'foreach' peut exécuter n'importe quel script Shell. Deux options pour tirer le dernier parti pourrait être,

git submodule foreach git pull Origin master

et,

git submodule foreach /path/to/some/cool/script.sh

Cela va parcourir tous les sous-modules initialized et exécuter les commandes données.

153
mturquette

Ce qui suit a fonctionné pour moi sous Windows.

git submodule init
git submodule update
142
zachleat

Modifier :

Dans les commentaires, il a été souligné (par philfreo ) que la dernière version est requise. S'il existe des sous-modules imbriqués qui doivent figurer dans leur dernière version:

git submodule foreach --recursive git pull

----- Commentaire dépassé ci-dessous -----

N'est-ce pas la manière officielle de le faire?

git submodule update --init

Je l'utilise à chaque fois. Aucun problème jusqu'à présent.

Modifier:

Je viens de trouver que vous pouvez utiliser:

git submodule foreach --recursive git submodule update --init 

Ce qui tirera également de manière récursive tous les sous-modules, à savoir les dépendances.

33
antitoxic

Comme il peut arriver que la branche par défaut de vos sous-modules soit pas master, voici comment j'automatise les mises à niveau complètes des sous-modules Git:

git submodule init
git submodule update
git submodule foreach 'git fetch Origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard Origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'
31
Sebastien Varrette

Première fois

Sous-module Clone et Init

git clone [email protected]:speedovation/kiwi-resources.git resources
git submodule init

Du repos

Pendant le développement, tirez et mettez à jour le sous-module

git pull --recurse-submodules  && git submodule update --recursive

Mettre à jour le sous-module Git avec le dernier commit sur Origin

git submodule foreach git pull Origin master

Manière préférée devrait être ci-dessous

git submodule update --remote --merge

note: les deux dernières commandes ont le même comportement

25
Yash

Je ne sais pas depuis quelle version de git cela fonctionne, mais c'est ce que vous recherchez:

git submodule update --recursive

Je l'utilise avec git pull pour mettre à jour le référentiel racine aussi:

git pull && git submodule update --recursive
18
Jens Kohl

Regardez http://lists.zerezo.com/git/msg674976.html qui introduit un paramètre --track

6
jerico.dev

Git pour Windows 2.6.3 :

git submodule update --rebase --remote

4
seoul

Les réponses ci-dessus sont bonnes, bien que nous utilisions git-hooks pour simplifier les choses, mais il s'avère que dans git 2.14, vous pouvez définir git config submodule.recurse sur true pour permettre aux sous-modules d'être mis à jour lorsque votre dépôt git.

Cela aura pour effet secondaire de pousser tous les changements de sous-modules que vous avez s'ils sont sur des branches, mais si vous avez déjà besoin de ce comportement, cela pourrait faire l'affaire.

Peut être fait en utilisant:

git config submodule.recurse true
3
JamesD

Voici la ligne de commande à extraire de tous vos référentiels git, qu'il s'agisse ou non de sous-modules:

ROOT=$(git rev-parse --show-toplevel 2> /dev/null)
find "$ROOT" -name .git -type d -execdir git pull -v ';'

Si vous l'exécutez dans votre référentiel git supérieur, vous pouvez remplacer "$ROOT" par ..

2
kenorb

Depuis le niveau le plus élevé dans le référentiel: Sous-module git pour chaque caisse de développement développer.

Cela changera toutes les branches pour développer et tirer les dernières

1
Srayan Guhathakurta

Remarque: manière pas trop facile, mais réalisable et il a ses propres avantages uniques.

Si vous voulez cloner uniquement la révision HEAD d'un référentiel et uniquement les HEADs de tous ses sous-modules (c'est-à-dire pour extraire "trunk"), vous pouvez utiliser le script suivant Lua. Parfois, une simple commande git submodule update --init --recursive --remote --no-fetch --depth=1 peut entraîner une erreur git irrécupérable. Dans ce cas, vous devez nettoyer le sous-répertoire du répertoire .git/modules et cloner le sous-module manuellement à l'aide de la commande git clone --separate-git-dir. La seule complexité est de trouver URL, le chemin du répertoire .git du sous-module et le chemin du sous-module dans l'arborescence du superprojet.

Remarque: le script est uniquement testé sur le référentiel https://github.com/boostorg/boost.git. Ses particularités: tous les sous-modules hébergés sur le même hôte et .gitmodules ne contiennent que des informations relatives URL.

-- mkdir boost ; cd boost ; lua ../git-submodules-clone-HEAD.lua https://github.com/boostorg/boost.git .
local module_url = arg[1] or 'https://github.com/boostorg/boost.git'
local module = arg[2] or module_url:match('.+/([_%d%a]+)%.git')
local branch = arg[3] or 'master'
function execute(command)
    print('# ' .. command)
    return os.execute(command)
end
-- execute('rm -rf ' .. module)
if not execute('git clone --single-branch --branch master --depth=1 ' .. module_url .. ' ' .. module) then
    io.stderr:write('can\'t clone repository from ' .. module_url .. ' to ' .. module .. '\n')
    return 1
end
-- cd $module ; git submodule update --init --recursive --remote --no-fetch --depth=1
execute('mkdir -p ' .. module .. '/.git/modules')
assert(io.input(module .. '/.gitmodules'))
local lines = {}
for line in io.lines() do
    table.insert(lines, line)
end
local submodule
local path
local submodule_url
for _, line in ipairs(lines) do
    local submodule_ = line:match('^%[submodule %"([_%d%a]-)%"%]$')
    if submodule_ then
        submodule = submodule_
        path = nil
        submodule_url = nil
    else
        local path_ = line:match('^%s*path = (.+)$')
        if path_ then
            path = path_
        else
            submodule_url = line:match('^%s*url = (.+)$')
        end
        if submodule and path and submodule_url then
            -- execute('rm -rf ' .. path)
            local git_dir = module .. '/.git/modules/' .. path:match('^.-/(.+)$')
            -- execute('rm -rf ' .. git_dir)
            execute('mkdir -p $(dirname "' .. git_dir .. '")')
            if not execute('git clone --depth=1 --single-branch --branch=' .. branch .. ' --separate-git-dir ' .. git_dir .. ' ' .. module_url .. '/' .. submodule_url .. ' ' .. module .. '/' .. path) then
                io.stderr:write('can\'t clone submodule ' .. submodule .. '\n')
                return 1
            end
            path = nil
            submodule_url = nil
        end
    end
end
1
Orient

Je pense que vous devrez écrire un script pour le faire. Pour être honnête, il se peut que j'installe python afin de pouvoir utiliser os.walk en cd dans chaque répertoire et exécuter les commandes appropriées. L'utilisation de python ou d'un autre langage de script, autre que batch, vous permettrait d'ajouter/supprimer facilement des sous-projets sans avoir à modifier le script.

1
baudtack

Tout ce que vous devez faire maintenant est un simple git checkout

Assurez-vous simplement de l'activer via cette configuration globale: git config --global submodule.recurse true

1
Pellet