web-dev-qa-db-fra.com

Git commit sur un sous-module commun (branche principale)

J'ai deux projets ou plus (appelons-les ProjectFoo et ProjectBar ) ayant un code commun que j'ai mis dans un sous-module.

Ma compréhension est que si je valide des modifications d'un sous-module de l'intérieur ProjectFoo ce sera dans une tête détachée que seuls tous Les clones ProjectFoo peuvent voir:

(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git commit -am "Common code fix."
(56f21fb0...) $ git Push
Everything up-to-date

C'est probablement parce que la branche master n'a pas changé. Je pourrais probablement faire quelque chose comme git checkout master && git merge Everything up-to-date mais cela semble assez moche. Peut-être un git reset --hard master ferait de même mais cela semble encore plus laid.

Comment avoir un code commun partagé par projet, mis à jour de l'intérieur les projets l'utilisant? En d'autres termes, la validation de ce sous-module doit mettre à jour tous les différents référentiels ( référentiels, pas seulement les clones ) qui utilisent ce même sous-module.

---- ÉDITER ----

Visiblement, mon référentiel extrait a été foiré et cassé. Cela aurait dû fonctionner dès le début comme ça (sur ProjectFoo dans cet exemple):

(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git commit -am "Common code fix."
(master) $ git Push
....
   fbfdd71..0acce63  master -> master
(master) $ cd ..
(master) $ git add ProjectFooBarCommoneSubmodule
(master) $ git commit -m "Submodule update."

Ensuite, pour obtenir ce changement à partir d'autres projets, comme ProjectBar :

(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git pull

Mettre à jour vers le dernier code commun. UNE git checkout master peut être requis s'il est sur une tête détachée.

59
Wernight

Réponse courte:

cd ProjectFooBarCommoneSubmodule
git checkout master
<Do your editing>
git commit --all -m "Lots of fixes"
git Push submodule_Origin master
cd ..

git add ProjectFooBarCommoneSubmodule
git commit -m "Bumped up the revision of ProjectFooBarCommoneSubmodule"
git Push Origin master

Le plus long:

Les sous-modules Git sont un mécanisme de dépendance, où le projet principal (disons A) définit une révision spécifiée dans un sous-projet (disons B), qui sera utilisée dans la construction du projet A. Pour que l'outil soit utile, le comportement doit être prévisible du point de vue de A: s. Les dépendances ne peuvent pas changer, sauf si quelqu'un décide d'incorporer la modification au projet A. Toutes sortes de choses désagréables pourraient se produire, si les modifications du projet B: s étaient automatiquement importées, dont les erreurs de compilation sont probablement les meilleures, car A remarquerait immédiatement les échecs. C'est pourquoi la tête de B: s est maintenue à l'état détaché.

L'état de B est stocké dans A (consultez git submodule status), et un changement de révision doit être effectué et validé en A, pour qu'il ait un effet. C'est ce qui se passe dans l'exemple ci-dessus, A modifie le numéro de révision stocké dans le référentiel et augmente la version à la dernière. Le processus devra également être répété dans l'autre référentiel principal, donc pas de commutateur automatique "use master" AFAIK.

BTW. Les chapitre du livre Git sur les sous-modules et les page de manuel des sous-modules contiennent de nombreuses informations utiles sur les sous-modules, comme l'utilisation normale et les pièges typiques. Vaut le détour.


EDIT: je vais essayer de mieux expliquer cela

J'ai pris la liberté de créer des exemples de projets sur mon compte github . Les commits sont vides de sens et contiennent du courrier indésirable, mais la configuration devrait être correcte. Veuillez le vérifier pour suivre.

ProjectFoo et ProjectBar partagent le code dans le sous-module commun.

ProjectFooBarCommoneSubmodule: master is 6850e4e4c1fac49de398

Dans ProjectFoo:

git submodule status

-6850e4e4c1fac49de39890703f21486ca04b87a0 commun

Dans ProjectBar:

git submodule status

-6850e4e4c1fac49de39890703f21486ca04b87a0 commun

Donc, les deux pointent vers la même révision, non? L'astuce consiste à voir que ProjectFoo et ProjectBar pointent vers la révision (6850e4e4c1fac49de39890703f21486ca04b87a0) pas la branche (master), bien que ce soit la même chose. Le premier est une tête détachée et l'autre une branche nommée.

Si vous voulez faire quelques corrections sur ProjectFooBarCommoneSubmodule, vous pouvez aller dans le sous-répertoire dans par ex. ProjectFoo et choisissez la branche au lieu de la révision :

git checkout master 
<Do your coding and pushing here>

Ensuite, remontez d'un répertoire et vérifiez l'état du sous-module git. Il devrait vous dire que vous n'êtes plus synchronisé. Par exemple

git submodule status

+ e24bd2bf45d52171a63b67ac05cd4be0ac965f60 commun (têtes/master-1-ge24bd2b)

Vous pouvez maintenant faire un ajout git, pour définir la référence à ce commit particulier (ge24bd ...), faire un commit, et après cela, la référence du sous-module pointe vers cette révision, qui se trouve également être maître sur ProjectFooBarCommoneSubmodule.

Maintenant, vous devez également mettre à jour la référence dans ProjectBar. Allez dans ProjectBar/common, et faites git fetch Origin (c'est une fusion rapide), faites

git checkout master 
cd ..
git add common
git commit -m "Bumped up the revision"
git Push Origin master # to publish the revision bump to everybody else

Ainsi, comme avec tout référentiel git, vous n'avez pas besoin de travailler sur une tête détachée. Vous pouvez soit travailler sur maître, soit créer une branche nommée. Dans les deux cas, assurez-vous que l'amont contient les modifications de ProjectFooBarCommoneSubmodule, sinon vous casserez ProjectFoo et ProjectBar, s'ils font référence à quelque chose qui n'existe pas. J'espère que cela l'a mieux expliqué

67
Kai Inkinen

Sur le submodule: git Push Origin HEAD:master

3
Hogdotmac

Remarquer:

git submodule foreach 'git commit -a'

échouera si l'un des sous-modules ne contient aucun engagement à faire.

Pour vous en débarrasser, vous devez forcer le résultat de la commande à 0.

git submodule foreach "git commit -am 'your comment' || echo ' '"

En utilisant l'écho canalisé, vous forcez la commande entière à revenir avec 0 et continuez à exécuter la commande commit sur les autres sous-modules

0

Je fais juste:

git submodule foreach git Push -u Origin master

0
rivanov

Si vous souhaitez valider et pousser tous les sous-modules à la fois, procédez comme suit:

git submodule foreach 'git commit -a' ;
git submodule foreach 'git Push --all' ;
git commit -a && \
git Push --all --recurse-submodules=on-demand
0
Anona112

Pour fusionner changé de détaché HEAD dans master, exécutez:

git rebase HEAD master

puis checkout master (utilisez -f pour force):

git checkout master

Si vous avez plusieurs sous-modules à gérer, utilisez: git submodule foreach, par exemple.

git submodule foreach git pull Origin master -r
0
kenorb