comment tirer dans plusieurs branches à la fois avec git?


13

Dans un référentiel, j'ai plusieurs branches, parmi lesquelles "master" et "develop", qui sont configurées pour suivre les branches distantes "origin / master" et "origin / develop".

Est-il possible de spécifier que je veux fusionner (avance rapide) à la fois master et develop?

Quand je le fais git pullmaintenant, je reçois quelque chose comme ça:

remote: Counting objects: 92, done.
remote: Compressing objects: 100% (56/56), done.
remote: Total 70 (delta 29), reused 28 (delta 8)
Unpacking objects: 100% (70/70), done.
From scm.my-site.com:my-repo
   5386563..902fb45  develop    -> origin/develop
   d637d67..ba81fb2  master     -> origin/master
Updating 5386563..902fb45
Fast-forward

toutes les branches distantes sont récupérées, mais seule la branche sur laquelle je suis actuellement est fusionnée avec sa branche distante correspondante.

Je dois donc faire git checkout master...

Switched to branch 'master'
Your branch is behind 'origin/master' by 106 commits, and can be fast-forwarded.

... puis à git pullnouveau, puis revenez au développement pour obtenir le résultat souhaité.

Je sais que je peux créer des alias / scripts qui effectuent ces étapes. Mais je veux éviter cela si possible, car il est sujet aux erreurs et peu efficace .
Edit: ok permettez-moi de reformuler cela. Mon objectif n'était pas de décourager ou de désapprouver la personnalisation du script / alias de git. Je préférerais simplement une solution intégrée si elle existe :)


J'ai essayé git pull origin refs/heads/develop:refs/remotes/origin/develop refs/heads/master:refs/remotes/origin/mastermais cela a provoqué la fusion du maître distant dans le développement ..
Superole

1
Pourquoi serait-il sujet aux erreurs ou inefficace? Git est destiné à être personnalisé comme celui-ci. BTW, pour éviter d'avoir à vérifier chaque branche, vous voudrez peut-être diviser votre pullen un fetchsuivi d'un mergedans chaque branche.
jjlin

@jjlin bien si je peux le faire sans vérifier chaque branche qui peut aider à l'efficacité. Il est sujet aux erreurs car la matrice des choses qui peuvent mal tourner et les effets que cela peut avoir sur le reste du script sont quelque peu complexes. Je ne dis pas qu'il est impossible de le rendre sûr, mais ce serait un compromis. Je préfère donc une solution intégrée si elle existe :)
Superole

Réponses:


11

Vous pouvez configurer un alias qui utilise git fetchavec refspecs pour fusionner rapidement vos branches avec une seule commande. Définissez-le comme un alias dans votre .gitconfigfichier utilisateur :

[alias]
    sync = "!sh -c 'git checkout --quiet --detach HEAD && \
                    git fetch origin master:master develop:develop ; \
                    git checkout --quiet -'"

Utilisation: git sync.

Voici pourquoi cela fonctionne:

  1. git checkout --quiet HEADvérifie directement votre commit actuel, vous mettant dans un état de tête détaché . De cette façon, si vous êtes sur masterou develop, vous détachez votre copie de travail de ces pointeurs de branche, leur permettant d'être déplacés (Git ne vous permettra pas de déplacer les références de branche pendant que votre copie de travail les aura extraites).

  2. git fetch origin master:master develop:developutilise des refspecs avec fetchpour avancer rapidement les branches masteret developdans votre référentiel local. La syntaxe indique fondamentalement à Git "voici une refspec de la forme <source>:<destination>, prenez-la <destination>et avancez-la rapidement au même point que <source>". Ainsi, les sources de l'alias sont les branches de origin, tandis que les destinations sont les versions de dépôt local de ces branches.

  3. Enfin, git checkout --quiet -vérifiez la dernière branche sur laquelle vous vous trouviez, qu'il y ait eu ou non un échec dans les commandes précédentes. Donc, si vous étiez allumé masterlorsque vous avez couru git syncet que tout réussit, vous quitterez l'état de tête détaché et vérifierez la nouvelle mise à jour master.

Voir aussi ma réponse à git: mettre à jour une branche locale sans la vérifier? .


Je ne comprends pas vraiment la magie détachée ici, pourquoi le pointeur à maîtriser ne peut-il pas être déplacé lorsque le développement est extrait? ... de toute façon j'ai essayé cela, et cela semble fonctionner sauf que maintenant je reçois "Votre branche est en avance sur 'origine / développement' par 1 commit."
Superole

... qui est résolu la prochaine fois que je tire
Superole

@Superole quelle branche est en avance origin/developlorsque vous utilisez l'alias? Cela n'aurait aucun sens si c'était votre developsuccursale locale . En outre, le pointeur de master peut être déplacé s'il developest extrait, le fait est que s'il masterest extrait, vous ne pouvez pas avancer rapidement mastercar cela affecterait votre copie de travail, c'est pourquoi vous détachez la copie de travail en premier en utilisant git checkout head. J'ai vu une autre réponse qui le décrivait comme "debout sur un rocher", vous devez descendre du rocher avant de pouvoir le déplacer.
40XUserNotFound

c'était en effet mon développement local. Et la raison doit être que cette extraction ne met pas à jour les branches de suivi. Si je comprends bien; une traction va chercher dans origine / développer, puis fusionner cela en développer.
Superole

Il est très important que cette réponse provoque fatal: bad config line xx in file xxx. qui est causée par le point-virgule. vous devez encapsuler la commande entière entre guillemets doubles pour éviter ce problème.
William Leung

1

Installez git-up . Il vous donne la commande git-upqui va extraire toutes les branches locales de votre référentiel.


sucré! Je vais vérifier cela à coup sûr.
Superole

2
heh: P Les déclarations que Windows prend en charge sont prévisibles. et une preuve rigoureuse n'a pas encore été formulée qu'il ne gâchera certainement pas la configuration de votre git, ne supprimera pas les données ou ne publiera pas de drôles de choses sur Hacker News en votre nom. , combiné avec le besoin de Ruby, m'a chassé. J'aime bien le concept.
Superole du

Heureux qu'il y ait une méthode du tout ... un peu nul, bien que chaque méthode nécessite un outil tiers. Tels que celui-ci et ceux avec une commande shell "recette" ou un alias utilisant un shell particulier (spécifique à la plate-forme).
0xC0000022L

0

Il semble qu'il n'y ait pas d'option intégrée pour que git puisse tirer dans plusieurs branches. Du moins pas dans la version 1.8.0. bien que la réponse de @ Cupcake en soit proche.

Cependant, le commentaire de @ jjlin m'a fait réaliser qu'au moins je n'ai pas besoin de tirer deux fois.

Une séquence légèrement plus efficace serait donc:

git pull
git checkout master
git merge origin/master
git checkout -

Inévitablement, j'ai fini par créer un alias, mais j'ai décidé de m'en retirer et de me concentrer uniquement sur l'avance rapide d'une branche différente.

[alias]
ffwd = "!_() { git checkout $1 && git merge --ff-only origin/$1 && git checkout -; }; _"

Bien sûr, sans test, cet alias suppose que je fournis un nom valide d'une branche ff'able comme 1er argument, et a un comportement non défini sinon. Il n'est pas non plus optimal pour les cas d'utilisation avec plus de deux branches, mais il me fournira ce dont j'ai besoin pour l'instant.

git pull
git ffwd master
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.