web-dev-qa-db-fra.com

Quel est le meilleur moyen (et le plus sûr) de fusionner une branche Git en maître?

Une nouvelle branche de master est créée, nous l'appelons test.

Il existe plusieurs développeurs qui s'engagent dans master ou créent d'autres branches, puis fusionnent dans master.

Supposons que le travail sur test prend plusieurs jours et que vous souhaitiez garder continuellement test mis à jour avec des commits dans master.

Je ferais git pull Origin master de test.

Question 1: Est-ce la bonne approche? D'autres développeurs auraient facilement pu travailler sur les mêmes fichiers, tout comme moi.


Mon travail sur test est terminé et je suis prêt à le fusionner pour revenir à master. Voici les deux façons dont je peux penser:

A:

git checkout test
git pull Origin master
git Push Origin test
git checkout master
git pull Origin test 

B:

git checkout test
git pull Origin master
git checkout master
git merge test

Je n'utilise pas --rebase parce que, de mon point de vue, Rebase obtiendra les modifications de master et empilera les miennes par-dessus, ce qui pourrait écraser les modifications apportées par d'autres personnes.

Question 2: Laquelle de ces deux méthodes a raison? Quelle est la différence là-bas?

Le but de tout cela est de garder ma branche test mise à jour avec ce qui se passe dans master et plus tard, je pourrais les réintégrer dans master dans l’espoir de garder le montage aussi linéaire que possible.

1917
moe

Comment je ferais ça

git checkout master
git pull Origin master
git merge test
git Push Origin master

Si j'ai une branche locale d'une télécommande, je ne me sens pas à l'aise de fusionner d'autres branches que celle-ci avec la télécommande. Aussi, je ne voudrais pas pousser mes modifications, jusqu'à ce que je sois satisfait de ce que je veux pousser et je ne voudrais pas non plus pousser des choses du tout, qui ne sont que pour moi et mon référentiel local. Dans votre description, il semble que test ne soit que pour vous? Donc, aucune raison de le publier.

git essaie toujours de respecter vos modifications et celles des autres, et il en sera de même de --rebase. Je ne pense pas pouvoir l'expliquer correctement, alors jetez un coup d'œil à le livre Git - Rebasing ou git-ready: Intro into rebasing pour une petite description. C'est une fonctionnalité assez cool

2774
KingCrunch

C'est une question très pratique, mais toutes les réponses ci-dessus ne sont pas pratiques.

Comme

git checkout master
git pull Origin master
git merge test
git Push Origin master

Cette approche a deux problèmes :

  1. C'est dangereux, car nous ne savons pas s'il existe des conflits entre la branche test et la branche master.

  2. Il "presserait" tous les tests de validation dans une validation de fusion sur le maître; c'est-à-dire que sur la branche principale, nous ne pouvons pas voir tous les journaux de modifications de la branche test.

Ainsi, lorsque nous soupçonnons des conflits, nous pouvons avoir les opérations suivantes de git:

git checkout test
git pull 
git checkout master
git pull
git merge --no-ff --no-commit test

Testez merge avant commit, évitez une validation rapide par --no-ff,

En cas de conflit, nous pouvons exécuter git status pour vérifier les détails des conflits et essayer de les résoudre.

git status

Une fois que nous avons résolu les conflits, ou s’il n’y en a pas, nous commit et Push eux

git commit -m 'merge test branch'
git Push

Mais de cette manière, l'historique des modifications consignées dans la branche test sera perdu, ce qui rendrait la branche principale difficile à comprendre pour les autres développeurs.

La meilleure méthode consiste donc à utiliser rebase à la place de merge (supposons qu'au moment où nous avons résolu les conflits de branches).

Voici un exemple simple, pour les opérations avancées, veuillez vous référer à http://git-scm.com/book/en/v2/Git-Branching-Rebasing

git checkout master
git pull
git checkout test
git pull
git rebase -i master
git checkout master
git merge test

Oui, lorsque vous avez terminé les tiges, tous les commits de la branche Test seront déplacés vers la tête de la branche Master. Le principal avantage du changement de base est que vous obtenez une histoire de projet linéaire et beaucoup plus propre.

La seule chose à éviter est la suivante: n'utilisez jamais rebase sur une branche publique, comme une branche principale.

Ne faites jamais d'opérations comme suit:

git checkout master
git rebase -i test

Détails pour https://www.atlassian.com/git/tutorials/merging-vs-rebasing/the-golden-rule-of-rebasing

appendice:

352
John Yin

Ni une modification de base ni une fusion ne doivent écraser les modifications de quiconque (sauf si vous choisissez de le faire lors de la résolution d'un conflit).

L’approche habituelle lors du développement est

git checkout master
git pull
git checkout test
git log master.. # if you're curious
git merge Origin/test # to update your local test from the fetch in the pull earlier

Lorsque vous êtes prêt à rejoindre le maître,

git checkout master
git log ..test # if you're curious
git merge test
git Push

Si vous craignez de casser quelque chose pendant la fusion, git merge --abort est là pour vous.

Utiliser Push puis tirer comme un moyen de fusionner est idiot. Je ne comprends pas non plus pourquoi vous faites passer le test à Origin.

86
raylu

Je voudrais d'abord rendre la branche à fusionner aussi propre que possible. Exécutez vos tests, assurez-vous que l'état est comme vous le souhaitez. Nettoyez les nouveaux commits de git squash .

Outre KingCrunches answer , je suggère d'utiliser

git checkout master
git pull Origin master
git merge --squash test
git commit
git Push Origin master

Vous avez peut-être effectué de nombreux commits dans l'autre branche, ce qui ne devrait être qu'un seul commit dans la branche maître. Pour que l'historique de validation soit aussi propre que possible, vous pouvez écraser tous vos validations de la branche test dans une validation de la branche principale (voir aussi: Git: Pour écraser ou ne pas écraser? ) . Ensuite, vous pouvez également réécrire le message de validation en un message très expressif. Quelque chose qui est facile à lire et à comprendre, sans fouiller dans le code.

edit: Vous pourriez être intéressé par

Donc sur GitHub, je finis par faire ce qui suit pour une branche de fonctionnalité mybranch:

Obtenez les dernières nouvelles de Origin

$ git checkout master
$ git pull Origin master

Trouvez le hachage de la base de fusion:

$ git merge-base mybranch master
c193ea5e11f5699ae1f58b5b7029d1097395196f

$ git checkout mybranch
$ git rebase -i c193ea5e11f5699ae1f58b5b7029d1097395196f

Maintenant, assurez-vous que seul le premier est pick, le reste est s:

pick 00f1e76 Add first draft of the Pflichtenheft
s d1c84b6 Update to two class problem
s 7486cd8 Explain steps better

Ensuite, choisissez un très bon message de commit et Push to GitHub. Faites la demande de traction alors.

Après la fusion de la demande d'extraction, vous pouvez la supprimer localement:

$ git branch -d mybranch

et sur GitHub

$ git Push Origin :mybranch
39
Martin Thoma

C'est le flux de travail que j'utilise dans mon travail avec l'équipe. Le scénario est comme vous l'avez décrit. Premièrement, lorsque j'ai fini de travailler sur test, je rebase avec maître pour extraire ce qui a été ajouté à maître pendant le temps où j'ai travaillé sur la branche test.

git pull -r upstream master

Cela va extraire les modifications apportées au maître puisque vous avez créé la branche test et les appliquer, puis appliquer les modifications que vous avez apportées pour tester "au-dessus" de l'état actuel du maître. Il peut y avoir des conflits ici, si les autres personnes ont apporté des modifications aux mêmes fichiers que ceux que vous avez modifiés dans Test. S'il y en a, vous devrez les corriger manuellement et les valider. Une fois que vous avez fait cela, vous pourrez passer à la branche principale et fusionner test sans aucun problème.

6
djheru

Vieux fil, mais je n'ai pas trouvé comment le faire. Cela pourrait être utile pour quelqu'un qui travaille avec rebase et veut fusionner tous les commits d'une branche sur le maître. S'il existe un conflit, vous pouvez le résoudre pour chaque commit.

Obtenir le Master et la branche à jour:

git checkout master
git pull --rebase Origin master
git checkout <branch_name>
git pull --rebase Origin <branch_name>

Fusionner la branche sur le maître:

git checkout <branch_name>
git rebase master

Si vous rencontrez des conflits lors de la réorganisation:

Tout d'abord, résolvez le conflit dans le fichier. Ensuite:

git add .
git rebase --continue

ne fois la refonte terminée, rebassez la branche sur le maître:

git checkout master
git rebase <branch_name>
4
Robin Wieruch

Je voudrais utiliser la méthode de rebase. Principalement parce que cela reflète parfaitement votre cas, c'est-à-dire. Ce que vous voulez faire est d'actualiser l'état de votre branche actuelle et de "faire semblant" comme si elle était basée sur la dernière.

Donc, sans même vérifier master, je voudrais:

git fetch Origin
git rebase -i Origin/master
# ...solve possible conflicts here

Bien sûr, le simple fait d’exporter depuis Origin n’actualise pas l’état local de votre master (car il ne réalise pas de fusion), mais c’est parfaitement acceptable pour notre propos - nous voulons éviter de changer de position, pour des raisons de gagner du temps.

3
user776686
git checkout master
git pull Origin master
# Merge branch test into master
git merge test

Après la fusion, si le fichier est modifié, alors, lors de la fusion, le message d'erreur "Résoudre le conflit" sera affiché.

Alors, vous devez d’abord résoudre tous vos conflits, vous devez à nouveau valider toutes vos modifications, puis Push.

git Push Origin master

C’est mieux de faire qui a fait des changements dans la branche de test, car il savait ce qu’il avait fait.

3
Vinay Sikarwar