Mettre à jour les branches Git depuis le maître

676

Je suis nouveau sur Git, et maintenant je suis dans cette situation:

  • J'ai quatre branches (master, b1, b2 et b3).
  • Après avoir travaillé sur b1-b3, j'ai réalisé que j'avais quelque chose à changer sur le maître de branche qui devrait être dans toutes les autres branches.
  • J'ai changé ce dont j'avais besoin masteret ... voici mon problème:

Comment mettre à jour toutes les autres branches avec le mastercode de branche?

Ionuț Staicu
la source
3
J'ai trouvé ma réponse ici: comment fusionner des fichiers sélectifs avec git-merge?
wjandrea
59
Encore une autre tâche simple rendue difficile par Git. Les développeurs Git devraient utiliser Stack Overflow comme feedback dans leur boucle SDLC. 300 000 personnes devraient indiquer que quelque chose ne va vraiment pas dans le flux de travail de Git. Ils doivent engager un expert UX car ils ne peuvent clairement pas le faire par eux-mêmes.
2018

Réponses:

621

Vous avez deux options:

Le premier est une fusion, mais cela crée un commit supplémentaire pour la fusion.

Commander chaque succursale:

git checkout b1

Fusionnez ensuite:

git merge origin/master

Appuyez ensuite sur:

git push origin b1

Alternativement, vous pouvez faire un rebase:

git fetch
git rebase origin/master
Chris Kooken
la source
15
Je suis préoccupé par cette approche. Lorsque j'exécute git log --graph, le graphique montre que le maître est réellement fusionné avec la branche de sujet. Cela causera-t-il un problème à long terme? Je pensais que la meilleure pratique était toujours de fusionner la branche thématique pour la maîtriser. Commentez s'il vous plaît.
Patrick
2
Recherchez ce problème si vous utilisez le flux de travail de fusion: randyfay.com/node/89
Hampus Ahlgren
22
Vous fusionnez master en b1. Pourquoi tu got push origin master... n'a pas de sens. Vous ne changez pas de branche principale. Je pense que c'est une erreur avec 119 votes positifs: /
Yves Lange
22
N'utilisez pas la méthode de fusion, git rebase masterc'est la bonne réponse
Weston Ganger
6
Pour ceux d'entre nous qui liront plus tard - la préoccupation de @Kursion à propos de la faute de frappe a été abordée par la rédaction de l'auteur. De plus, la deuxième réponse la plus élevée ci-dessus indique essentiellement la même chose que cette réponse, mais avec un diagramme de la structure de la branche et un avertissement expliquant pourquoi vous ne voudriez pas rebaser.
Beyondtheteal
496

Vous avez essentiellement deux options:

  1. Vous fusionnez. C'est en fait assez simple, et une opération parfaitement locale:

    git checkout b1
    git merge master
    # repeat for b2 and b3
    

    Cela laisse l'historique exactement tel qu'il s'est produit: vous avez dérivé de master, vous avez apporté des modifications à toutes les branches, et enfin vous avez incorporé les modifications de master dans les trois branches.

    gitpeut très bien gérer cette situation, il est conçu pour les fusions qui se produisent dans toutes les directions, en même temps. Vous pouvez lui faire confiance pour pouvoir réunir correctement tous les threads. Il ne se soucie simplement pas de savoir si la branche b1fusionne masterou masterfusionne b1, la validation de la fusion ressemble tout de même à git. La seule différence est, quelle branche finit par pointer vers ce commit de fusion.

  2. Vous rebasez. Les personnes possédant un SVN ou des antécédents similaires trouvent cela plus intuitif. Les commandes sont analogues au cas de fusion:

    git checkout b1
    git rebase master
    # repeat for b2 and b3
    

    Les gens aiment cette approche car elle conserve une histoire linéaire dans toutes les branches. Cependant, cette histoire linéaire est un mensonge, et vous devez être conscient qu'elle l'est. Considérez ce graphique de validation:

    A --- B --- C --- D <-- master
     \
      \-- E --- F --- G <-- b1
    

    La fusion entraîne la véritable histoire:

    A --- B --- C --- D <-- master
     \                 \
      \-- E --- F --- G +-- H <-- b1
    

    Le rebase, cependant, vous donne cette histoire:

    A --- B --- C --- D <-- master
                       \
                        \-- E' --- F' --- G' <-- b1
    

    Le fait est que les engagements E', F'et G'n'ont jamais vraiment existé, et n'ont probablement jamais été testés. Ils peuvent même ne pas compiler. Il est en fait assez facile de créer des commits absurdes via un rebase, surtout lorsque les changements dans mastersont importants pour le développement deb1 .

    La conséquence de cela peut être que vous ne pouvez pas distinguer lequel des trois commits E,F et en Gfait introduit une régression, ce qui diminue la valeur de git bisect.

    Je ne dis pas que vous ne devriez pas utiliser git rebase. Il a ses utilisations. Mais chaque fois que vous l'utilisez, vous devez être conscient du fait que vous mentez sur l'histoire. Et vous devez au moins compiler tester les nouveaux commits.

cmaster - réintégrer monica
la source
Je fusionnait une autre branche source (non maître) et des mesures supplémentaires pour ajouter à cette belle réponse a été de mettre à jour sur mon repo local avant la fusion (pour avoir le dernier code local): git checkout <source branch> git pull. Puis continuant avec ci-dessus: git checkout b1...
Rod
3
En tant qu'utilisateur de longue date de SVN, je préfère l'option de fusion au rebasage: en utilisant n'importe quel contrôle de version, il est très, très important de conserver des enregistrements précis des modifications que vous avez apportées et pourquoi. Je peux voir l'intérêt du rebase pour simplifier l'historique apparent, mais vous devriez ensuite revenir en arrière et ajouter aux commentaires de validation de E ', F', G '- et de préférence avoir le rebase automatiquement ajouté à ces commentaires. Sinon, si le processus de génération / test / test-déploiement échoue sur G ', vous devez déterminer pourquoi les modifications ont été apportées sans informations complètes.
WillC
13
L'histoire est un mensonge
piratemurray
Merci j'utilise "git merge any-branch-name" pour fusionner un code de branche à une autre branche. Localement, je peux tester le code de la branche 1 pendant que je suis sur la branche 2
Priti
1
@blamb Les conflits de fusion se produisent avec git mergeet git rebase. Il est impossible de les éviter. git rebasea l'avantage de vous permettre de masquer plusieurs étapes de rebasage (c'est-à-dire de rebaser la même branche sur plusieurs validations différentes en séquence pour réduire le nombre de conflits à chaque étape). Néanmoins, le simple fait qu'une rebase ment sur l'histoire facilite beaucoup la baise dans une telle rebase à plusieurs étages ... C'est pourquoi je préfère toujours la fusion, même quand cela signifie que je dois encombrer l'histoire avec plusieurs validations de fusion .
cmaster - réintègre monica le
238

git rebase masterest la bonne façon de le faire. La fusion signifierait qu'un commit serait créé pour la fusion, contrairement au rebasage.

Michael J. Gray
la source
52
Qu'en est-il lorsque vous avez déjà poussé vers l'origine, si vous rebase vous réécrivez l'historique de validation et cela entrera en conflit avec votre branche distante. Je pense que rebase ne devrait être utilisé que sur un pull ou lorsque vous n'avez pas poussé vers une branche distante.
Matt Smith du
6
Si vous êtes le seul à travailler sur la branche distante, vous pouvez utiliser la fonction git push --force origin pour mettre à jour votre branche distante avec une branche locale rebasée. stackoverflow.com/questions/8939977/…
stormwild
7
rebaser et fusionner les deux œuvres, rebaser est préférable pour les branches privées, car il donne un graphique d'historique plus propre. cette réponse est la meilleure
Junchen Liu
5
Besoin d'être plus clair sur le compromis entre la clarté (idéal pour un seul utilisateur ou une petite équipe) ou la vérité désordonnée (pour les branches de code multi-contributeurs - nécessaire pour la maintenabilité (dans mon expérience - YMMV)).
WillC
1
re "et si vous avez déjà poussé?" -> La règle d'or de git rebase est de ne jamais l'utiliser sur les branches publiques .
Trevor Boyd Smith
53

Si vous avez travaillé sur une branche de façon intermittente, ou que beaucoup de choses se sont produites dans d'autres branches pendant que vous travailliez sur quelque chose, il est préférable de rebaser votre branche sur master. Cela permet de garder l'historique bien rangé et rend les choses beaucoup plus faciles à suivre.

git checkout master
git pull
git checkout local_branch_name
git rebase master
git push --force # force required if you've already pushed

Remarques:

  • Ne rebasez pas les branches sur lesquelles vous avez collaboré avec d'autres.
  • Vous devez rebaser sur la branche vers laquelle vous allez fusionner qui n'est pas toujours maître.

Il y a un chapitre sur le rebasage sur http://git-scm.com/book/ch3-6.html , et de nombreuses autres ressources sur le Web.

Simon Bingham
la source
Merci pour la solution simple
autre grand gars
18

@cmaster a fait la meilleure réponse élaborée. En bref:

git checkout master #
git pull # update local master from remote master
git checkout <your_branch>
git merge master # solve merge conflicts if you have`

Vous ne devez pas réécrire l'historique des branches au lieu de les conserver dans leur état réel pour de futures références. Lors de la fusion vers master, il crée un commit supplémentaire mais c'est bon marché. Les engagements ne coûtent pas.

lune bleue
la source
13

Pour mettre à jour d'autres branches comme (sauvegarde) avec votre copie de branche principale. Vous pouvez suivre les deux méthodes (rebaser ou fusionner) ...

  1. Faites une nouvelle base (il n'y aura pas de validation supplémentaire dans la branche de sauvegarde).
  2. Fusionner les branches (il y aura automatiquement un commit supplémentaire dans la branche de sauvegarde).

    Remarque: Rebase n'est rien d'autre que l'établissement d'une nouvelle base (une nouvelle copie)

git checkout backup
git merge master
git push

(Répétez l'opération pour les autres branches, le cas échéant, comme backup2, etc.)

git checkout backup
git rebase master
git push

(Répétez l'opération pour les autres branches, le cas échéant, comme backup2, etc.)

Sundar Gsv
la source
9

Vous pouvez fusionner, ou vous pouvez appliquer des validations individuelles entre les branches en utilisant git cherry-pick .

Brian Agnew
la source
1

Il existe deux options pour ce problème.

1) git rebase

2) Git Merge

Seul diff avec au-dessus des deux en cas de fusion, aura un commit supplémentaire dans l'historique

1) Git Checkout Branch (B1, B2, B3)

2) git rebase origin / master (En cas de conflits, résolvez localement en faisant git rebase --continue)

3) git push

Alternativement, l'option de fusion git est similaire

1) git checkout "your_branch" (b1, b2, b3)

2) Git Merge Master

3) git push

kris
la source
1

pour mettre à jour votre branche depuis le maître:

  git checkout master
  git pull
  git checkout your_branch
  git merge master
D_Oghli
la source