Comment ça git submodule add -b
marche?
Après avoir ajouté un sous-module avec une branche spécifique, un nouveau référentiel cloné (après git submodule update --init
) sera à un commit spécifique, pas la branche elle-même ( git status
sur le sous-module affiche "Pas actuellement sur une branche").
Je ne trouve aucune information sur .gitmodules
ou à .git/config
propos de la branche du sous-module ou d'un commit spécifique, alors comment Git peut-il le comprendre?
Est-il également possible de spécifier une balise au lieu d'une branche?
J'utilise la version 1.6.5.2.
git
git-submodules
Ivan
la source
la source
Réponses:
Remarque: Git 1.8.2 a ajouté la possibilité de suivre les branches. Voir certaines des réponses ci-dessous.
C'est un peu déroutant de s'y habituer, mais les sous-modules ne sont pas sur une branche. Ils ne sont, comme vous le dites, qu'un pointeur vers une validation particulière du référentiel du sous-module.
Cela signifie que lorsque quelqu'un d'autre extrait votre référentiel, ou extrait votre code, et met à jour le sous-module git, le sous-module est extrait pour ce commit particulier.
C'est idéal pour un sous-module qui ne change pas souvent, car alors tout le monde sur le projet peut avoir le sous-module au même commit.
Si vous souhaitez déplacer le sous-module vers une balise particulière:
Ensuite, un autre développeur qui souhaite que submodule_directory soit modifié pour cette balise, le fait
git pull
les modifications qui valident leur répertoire de sous-module pointe vers.git submodule update
fusionne réellement dans le nouveau code.la source
cd my_submodule; git checkout [ref in submodule's repository
rendementsfatal: reference is not a tree: ...
. C'est comme sigit
ne fonctionnerait que sur le référentiel parent.git checkout v1.0
une branche ou un tag?J'aimerais ajouter ici une réponse qui n'est en réalité qu'un conglomérat d'autres réponses, mais je pense qu'elle pourrait être plus complète.
Vous savez que vous avez un sous-module Git lorsque vous avez ces deux choses.
Votre
.gitmodules
a une entrée comme ceci:Vous avez un objet sous-module (nommé SubmoduleTestRepo dans cet exemple) dans votre référentiel Git. GitHub les présente comme des objets "sous-modules". Ou faites à
git submodule status
partir d'une ligne de commande. Les objets de sous-module Git sont des types spéciaux d'objets Git, et ils contiennent les informations SHA pour une validation spécifique.Chaque fois que vous effectuez un
git submodule update
, il remplira votre sous-module avec le contenu de la validation. Il sait où trouver le commit à cause des informations contenues dans le fichier.gitmodules
.Maintenant, tout ce qu'il
-b
faut, c'est ajouter une ligne dans votre.gitmodules
fichier. Donc, suivant le même exemple, cela ressemblerait à ceci:L'objet sous-module pointe toujours sur une validation spécifique. La seule chose que l'
-b
option vous achète est la possibilité d'ajouter un--remote
indicateur à votre mise à jour selon la réponse de Vogella:Au lieu de renseigner le contenu du sous-module sur la validation pointée par le sous-module, il remplace cette validation par la dernière validation sur la branche principale, PUIS il remplit le sous-module avec cette validation. Cela peut se faire en deux étapes par réponse djacobs7. Puisque vous avez maintenant mis à jour la validation vers laquelle l'objet du sous-module pointe, vous devez valider l'objet de sous-module modifié dans votre référentiel Git.
git submodule add -b
n'est pas un moyen magique de tout garder à jour avec une branche. Il ajoute simplement des informations sur une branche dans le.gitmodules
fichier et vous donne la possibilité de mettre à jour l'objet de sous-module à la dernière validation d'une branche spécifiée avant de le remplir.la source
.gitmodules
et après avoir$ git submodule update --init --remote TestModule
fait une erreur disantfatal: Needed a single revision
etUnable to find current origin/TestTag revision in submodule path 'TestModule'
. Lorsque vous le faites avec une vraie branche, cela fonctionne. Est-il possible de spécifier une balise.gitmodules
sans avoir à spécifier le commit exact?.gitmodules
et j'ai courugit submodule update
et il ne s'est rien passé?(Git 2.22, Q2 2019, a introduit
git submodule set-branch --branch aBranch -- <submodule_path>
)Notez que si vous avez un sous-module existant qui ne suit pas encore une branche , alors ( si vous avez git 1.8.2+ ):
Assurez-vous que le dépôt parent sait que son sous-module suit désormais une branche:
Assurez-vous que votre sous-module est bien au plus tard de cette branche:
(«origine» étant le nom du référentiel distant en amont à partir duquel le sous-module a été cloné.
Un
git remote -v
intérieur de ce sous-module l'affichera. Généralement, il s'agit de «origine»)N'oubliez pas d'enregistrer le nouvel état de votre sous-module dans votre référentiel parent:
La mise à jour ultérieure de ce sous-module devra utiliser l'
--remote
option:Notez qu'avec Git 2.10+ (Q3 2016), vous pouvez utiliser '
.
' comme nom de branche:Mais, comme commenté par LubosD
Cela signifie Git 2.23 (août 2019) ou plus.
Voir " Confus par
git checkout
"Si vous souhaitez mettre à jour tous vos sous-modules en suivant une branche:
Notez que le résultat, pour chaque sous-module mis à jour, sera presque toujours une tête détachée , comme le note Dan Cameron dans sa réponse .
( Clintm note dans les commentaires que, si vous exécutez
git submodule update --remote
et que le sha1 résultant est le même que la branche sur laquelle le sous-module est actuellement, il ne fera rien et laissera le sous-module toujours "sur cette branche" et non dans un état de tête détachée. )Pour s'assurer que la branche est réellement extraite (et cela ne modifiera pas le SHA1 de l' entrée spéciale représentant le sous-module pour le référentiel parent), il suggère:
Chaque sous-module référencera toujours le même SHA1, mais si vous effectuez de nouveaux commits, vous pourrez les pousser car ils seront référencés par la branche que vous souhaitez que le sous-module suive.
Après cette poussée dans un sous-module, n'oubliez pas de revenir au référentiel parent, d'ajouter, de valider et de pousser le nouveau SHA1 pour ces sous-modules modifiés.
Notez l'utilisation de
$toplevel
, recommandée dans les commentaires d' Alexander Pogrebnyak .$toplevel
a été introduit dans git1.7.2 en mai 2010: commit f030c96 .dtmland
ajoute dans les commentaires :La même commande mais plus facile à lire:
umläute affine la commande de dtmland avec une version simplifiée dans les commentaires :
plusieurs lignes:
Avant Git 2.26 (T1 2020), une extraction à laquelle il est demandé de récupérer récursivement les mises à jour dans les sous-modules produit inévitablement des rames de sortie, et il devient difficile de repérer les messages d'erreur.
La commande a appris à énumérer les sous-modules qui avaient des erreurs à la fin de l'opération .
Voir commit 0222540 (16 janvier 2020) par Emily Shaffer (
nasamuffin
) .(Fusionné par Junio C Hamano -
gitster
- en commit b5c71cc , 05 fév 2020)la source
foreach
script ne dépendra pas du code en dur<path>
, si vous le remplacez<path>
par$toplevel/
.foreach
script ne parviendra pas à extraire les sous-modules qui ne suivent pas une branche. Cependant, cette commande vous donne les deux:git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git checkout $branch'
git submodule foreach -q --recursive 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
git submodule update --remote --merge
ougit submodule update --remote --rebase
. Ces commandes effectuent le suivi de la branche distante.Git 1.8.2 a ajouté la possibilité de suivre les branches.
Voir aussi sous-modules Git
la source
.gitmodules
fichier?git submodule add -b tags/<sometag> <url>
laquelle vous pouvez voir la lignebranch = tags/<sometag>
en.gitmodules
Un exemple de la façon dont j'utilise les sous-modules Git.
Et cela ressemble un peu à ceci:
Peut-être que cela aide (même si j'utilise une balise et non une branche)?
la source
git reset --hard V3.1.2
? Je reçois juste un "rien à valider" avec ungit status
du répertoire parent.D'après mon expérience, le changement de branche dans le superprojet ou les extractions futures entraînera toujours des TÊTES détachées de sous-modules, que le sous-module soit correctement ajouté et suivi (c.-à-d. Réponses @ djacobs7 et @Johnny Z).
Et au lieu de vérifier manuellement la branche correcte manuellement ou via un script git, le sous-module foreach peut être utilisé.
Cela vérifiera le fichier de configuration du sous-module pour la propriété de la branche et extraira la branche définie.
git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'
la source
Les sous-modules Git sont un peu étranges - ils sont toujours en mode "tête détachée" - ils ne sont pas mis à jour avec le dernier commit sur une branche comme on pourrait s'y attendre.
Cela a du sens quand on y pense, cependant. Disons que je crée un référentiel foo avec une barre de sous-module . Je pousse mes modifications et vous dis de vérifier le commit a7402be depuis le dépôt foo .
Imaginez ensuite que quelqu'un valide une modification de la barre de référentiel avant de pouvoir faire votre clone.
Lorsque vous extrayez commit a7402be à partir du référentiel foo , vous vous attendez à obtenir le même code que j'ai poussé. C'est pourquoi les sous-modules ne sont pas mis à jour tant que vous ne leur avez pas demandé explicitement de faire un nouveau commit.
Personnellement, je pense que les sous-modules sont la partie la plus déroutante de Git. Il y a beaucoup d'endroits qui peuvent expliquer les sous-modules mieux que moi. Je recommande Pro Git de Scott Chacon.
la source
git clone git://github.com/git/git.git
et pousser cette fonctionnalité ...? = DPour changer de branche pour un sous-module (en supposant que vous avez déjà le sous-module dans le référentiel):
cd
à la racine de votre référentiel contenant les sous-modules.gitmodules
pour modificationpath = ...
- dessous eturl = ...
cela ditbranch = your-branch
, pour chaque sous-module; enregistrer le fichier.gitmodules
.$ git submodule update --remote
... cela devrait générer les derniers commits sur la branche spécifiée, pour chaque sous-module ainsi modifié.
la source
Je l'ai dans mon fichier .gitconfig. Il s'agit toujours d'un projet, mais il s'est avéré utile pour l'instant. Cela m'aide à toujours rattacher les sous-modules à leur branche.
la source
Nous utilisons Quack pour extraire un module spécifique d'un autre référentiel Git. Nous devons extraire le code sans l'intégralité de la base de code du référentiel fourni - nous avons besoin d'un module / fichier très spécifique de cet immense référentiel et doit être mis à jour chaque fois que nous exécutons la mise à jour.
Nous l'avons donc réalisé de cette manière:
Créer une configuration
Avec la configuration ci-dessus, il crée un répertoire à partir du référentiel GitHub fourni comme spécifié dans la configuration du premier module, et l'autre consiste à extraire et à créer un fichier à partir du référentiel donné.
Les autres développeurs ont juste besoin de s'exécuter
Et il tire le code des configurations ci-dessus.
la source
Le seul effet du choix d'une branche pour un sous-module est que, chaque fois que vous passez l'
--remote
option dans lagit submodule update
ligne de commande, Git extrait en mode HEAD détaché (si le--checkout
comportement par défaut est sélectionné) la dernière validation de cette branche distante sélectionnée .Vous devez être particulièrement prudent lorsque vous utilisez cette fonction de suivi de branche à distance pour les sous-modules Git si vous travaillez avec des clones peu profonds de sous-modules. La branche que vous choisissez à cet effet dans les paramètres de sous-module N'EST PAS celle qui sera clonée pendant
git submodule update --remote
. Si vous passez également le--depth
paramètre et que vous n'indiquez pas à Git sur quelle branche vous voulez cloner - et en fait vous ne pouvez pas dans lagit submodule update
ligne de commande !! -, il se comportera implicitement comme expliqué dans lagit-clone(1)
documentationgit clone --single-branch
lorsque le--branch
paramètre explicite est manquant, et par conséquent il ne clonera que la branche primaire .Sans surprise, après l'étape de clonage effectuée par la
git submodule update
commande, il va enfin essayer de vérifier la dernière validation de la branche distante que vous avez précédemment configurée pour le sous-module, et, si ce n'est pas la principale, elle ne fait pas partie de votre clone peu profond local, et donc il échouera avecla source
git submodule add -b develop --name branch-name - https: //branch.git
la source