1345 votes

Git fusionne la branche hotfix dans la branche feature

Disons que nous avons la situation suivante dans Git :

  1. Un référentiel créé :

    mkdir GitTest2
    cd GitTest2
    git init
  2. Certaines modifications du maître ont lieu et sont enregistrées :

    echo "On Master" > file
    git commit -a -m "Initial commit"
  3. Feature1 s'est branché sur master et du travail a été fait :

    git branch feature1
    git checkout feature1
    echo "Feature1" > featureFile
    git commit -a -m "Commit for feature1"
  4. Pendant ce temps, un bogue est découvert dans le code maître et une branche de correction est établie :

    git checkout master
    git branch hotfix1
    git checkout hotfix1
  5. Le bogue est corrigé dans la branche hotfix et réintégré dans le master (peut-être après une pull request/une révision du code) :

    echo "Bugfix" > bugfixFile
    git commit -a -m "Bugfix Commit"
    git checkout master
    git merge --no-ff hotfix1
  6. Le développement de la fonctionnalité 1 se poursuit :

    git checkout feature1

Disons que j'ai besoin du correctif dans ma branche de fonctionnalité, peut-être parce que le bogue s'y produit également. Comment puis-je y parvenir sans dupliquer les commits dans ma branche de fonctionnalités ?

Je veux éviter de recevoir deux nouveaux commits sur ma branche de fonctionnalité qui n'ont aucun rapport avec l'implémentation de la fonctionnalité. Cela me semble particulièrement important si j'utilise des demandes de téléchargement : Tous ces commits seront également inclus dans la demande de pull et devront être revus bien que cela ait déjà été fait (puisque le correctif est déjà dans le master).

Je ne peux pas faire un git merge master --ff-only : "fatal : Impossible d'effectuer une avance rapide, abandon", mais je ne suis pas sûr que cela m'ait aidé.

13 votes

Si la branche feature1 est complètement local, jetez un coup d'œil à git rebase .

31 votes

Merci, en tant que débutant de git, git rebase ça ressemble à de la magie noire pour moi....

13 votes

Si la branche est fonctionnalité -Seulement, la correction du bug ne devrait pas avoir lieu ici (du moins si ce n'est pas un bug bloquant) puisque le but de cette branche est de montrer une nouvelle fonctionnalité. Le bug sera corrigé lors de la fusion avec le master où le commit avec la correction est présent.

1626voto

Sven Points 14241

Comment fusionner la branche master avec la branche feature ? Facile :

git checkout feature1
git merge master

Il ne sert à rien de forcer une fusion en avance rapide ici, car cela ne peut se faire. Vous avez commis à la fois dans la branche des fonctionnalités et dans la branche principale. L'avance rapide est impossible maintenant.

Jetez un coup d'œil à GitFlow . C'est un modèle de branchement pour git que l'on peut suivre, et que vous avez inconsciemment déjà suivi. Il s'agit également d'une extension de Git qui ajoute certaines commandes pour les nouvelles étapes du flux de travail qui font automatiquement des choses que vous auriez autrement dû faire manuellement.

Alors, qu'avez-vous fait de bien dans votre flux de travail ? Vous avez deux branches avec lesquelles travailler, votre branche feature1 est fondamentalement la branche "develop" dans le modèle GitFlow.

Vous avez créé une branche hotfix à partir de master et l'avez fusionnée. Et maintenant vous êtes coincé.

Le modèle GitFlow vous demande de fusionner le correctif également à la branche de développement, qui est "feature1" dans votre cas.

Donc la vraie réponse serait :

git checkout feature1
git merge --no-ff hotfix1

Cela ajoute tous les changements qui ont été faits dans le correctif à la branche des fonctionnalités, mais sólo ces changements. Ils peuvent entrer en conflit avec d'autres changements de développement dans la branche, mais ils n'entreront pas en conflit avec la branche master si vous fusionnez la branche des fonctionnalités vers master par la suite.

Soyez très prudent avec le rebasement. Ne rebasez que si les changements que vous avez effectués restent locaux à votre dépôt, c'est-à-dire que vous n'avez pas poussé de branches vers un autre dépôt. Le rebasement est un excellent outil qui vous permet d'organiser vos commits locaux dans un ordre utile avant de les pousser dans le monde, mais le rebasement après coup va tout gâcher pour les débutants de git comme vous.

5 votes

Ce flux de travail ne conduit-il pas à de nombreux commits inutiles et dupliqués ? Le commit de la branche hotfix est copié dans ma branche feature et ensuite fusionné dans le master. Cela ne conduit-il pas au fait que le commit apparaît deux fois dans le journal de commit ?

7 votes

Non. Le commit corrigeant le bogue n'apparaît qu'une seule fois dans la branche hotfix, même si le nom de la branche est supprimé une fois qu'elle a été fusionnée dans les branches master et devel. Le commit de fusion ne montre que les changements introduits par la fusion, ce qui ressemble à un commit dupliqué. Mais c'est ainsi que fonctionne git : Branch et merge en retour. Le véritable travail de développement n'a lieu que dans les commits non fusionnés, et la fusion n'est acceptée que si le résultat est un logiciel fonctionnel.

44 votes

Cela devrait être la réponse acceptée. Elle fonctionne également bien avec la fonction de demande de tirage de GitHub.

664voto

David Sulc Points 13259

Vous devriez être en mesure de rebaser votre branche sur master :

git checkout feature1
git rebase master

Gérez tous les conflits qui surviennent. Lorsque vous arrivez aux commits avec les corrections de bogues (déjà dans master), Git dira qu'il n'y a pas eu de changements et qu'ils ont peut-être déjà été appliqués. Vous continuez alors le rebasement (en sautant les commits déjà dans master) avec

git rebase --skip

Si vous effectuez un git log sur votre branche de fonctionnalité, vous verrez le commit de correction de bogue apparaître une seule fois, et dans la partie master.

Pour une discussion plus détaillée, jetez un coup d'œil à la documentation du livre de Git sur git rebase ( https://git-scm.com/docs/git-rebase ) qui couvrent exactement ce cas d'utilisation.

\================ Editer pour un contexte supplémentaire ====================

Cette réponse a été fournie spécifiquement pour la question posée par @theomega, en tenant compte de sa situation particulière. Notez cette partie :

Je veux empêcher [...] commits sur ma branche de fonctionnalité qui n'ont aucune relation avec l'implémentation de la fonctionnalité.

Rebaser sa branche privée sur master est exactement ce qui donnera ce résultat. En revanche, la fusion de master dans sa branche ferait précisément ce qu'il ne veut surtout pas que cela se produise : ajouter un commit qui n'est pas lié à l'implémentation de la fonctionnalité sur laquelle il travaille via sa branche.

Pour les utilisateurs qui lisent le titre de la question, ignorent le contenu réel et le contexte de la question, puis ne lisent que la réponse la plus élevée en supposant qu'elle s'appliquera toujours à leur cas d'utilisation (différent), permettez-moi d'élaborer :

  • ne rebase que les branches privées (c'est-à-dire celles qui n'existent que dans votre dépôt local et qui n'ont pas été partagées avec d'autres). Rebaser des branches partagées "casserait" les copies que d'autres personnes peuvent avoir.
  • si vous voulez intégrer des changements d'une branche (qu'il s'agisse de master ou d'une autre branche) dans une branche publique (par exemple, vous avez poussé la branche pour ouvrir une demande de pull, mais il y a maintenant des conflits avec master, et vous devez mettre à jour votre branche pour résoudre ces conflits), vous devrez les fusionner (par exemple avec git merge master comme dans la réponse de @Sven).
  • vous pouvez également fusionner des branches dans vos branches privées locales si c'est votre préférence, mais soyez conscient que cela entraînera des commits "étrangers" dans votre branche.

Enfin, si vous êtes mécontent du fait que cette réponse n'est pas la plus adaptée à votre situation, même si elle l'était pour @theomega, ajouter un commentaire ci-dessous ne sera pas particulièrement utile : Je ne contrôle pas la réponse qui sera sélectionnée, seul @theomega le fait.

6 votes

Bon, supposons que j'ai déjà poussé la branche vers github pour une demande de pull (dans une branche du dépôt principal). Est-il toujours possible de faire le git rebase (en supposant que personne n'a vérifié ma branche) ?

145 votes

Non, ce n'est pas sûr : si vous rebasez, vous modifiez l'historique de la branche, ce qui affectera les développeurs qui ont tiré la branche. inf act, git ne vous laissera pas pousser une branche rebasée par défaut : vous devez forcer la mise à jour avec -f lors du push pour écraser la branche avec la version rebasée. Attention !

21 votes

Comment les équipes professionnelles utilisant git gèrent-elles ce problème ? Est-ce qu'elles se contentent de prêter attention, de réfléchir attentivement et de faire un -f ? Ou est-ce que mon flux de travail complet est défectueux parce que j'ai besoin d'un -f ?

89voto

xgqfrms Points 2718

git merge

vous pouvez suivre les étapes suivantes

1. fusionner origin/master à la branche feature branche

# step1: change branch to master, and pull to update all commits
$ git checkout master
$ git pull

# step2: change branch to target, and pull to update commits
$ git checkout feature
$ git pull

# step3: merge master to feature( current is feature branch)
$ git merge master

2. fusionner feature à la branche origin/master branche

origin/master est la branche maîtresse distante, tandis que master est la branche maîtresse locale

$ git checkout master
$ git pull origin/master

$ git merge feature
$ git push origin/master

0 votes

0 votes

2 votes

J'ai l'impression que rebase est pressé ! La bonne vieille fusion :) !

76voto

zimi Points 400

Sur la base de cet article vous devriez :

  • créer une nouvelle branche qui est basée sur la nouvelle version de master

    git branch -b newmaster

  • fusionner votre ancienne branche de fonctionnalité dans la nouvelle

    git checkout newmaster

  • résoudre le conflit sur la branche des nouvelles fonctionnalités

Les deux premières commandes peuvent être combinées pour git checkout -b newmaster .

De cette façon, votre historique reste clair car vous n'avez pas besoin de faire de rétro-fusions. Et vous n'avez pas besoin d'être aussi prudent puisque vous n'avez pas besoin de faire une rebase Git.

8 votes

Ce serait bien si vous faisiez suivre chaque point par la commande git correspondante. Sinon, il me semble que c'est effectivement l'option la plus sûre et la plus propre.

0 votes

@zimi Qu'en est-il si nous avons une branche distante ? Allons-nous recréer la branche de la nouvelle fonctionnalité de mise à jour à nouveau ? Ou pouvons-nous simplement définir remote-upstream ?

0 votes

@VirgileD Je viens de poster ma propre réponse avec plus de détails, y compris les commandes git correspondantes.

36voto

J'ajoute ma réponse, semblable à celle des autres mais qui sera peut-être la plus rapide à lire et à mettre en œuvre.

NOTE : Le rebasement n'est pas nécessaire dans ce cas.

Supposons que j'ai un repo1 et deux branches master y dev-user .

dev-user est une branche faite à un certain état de master .

Supposons maintenant que les deux dev-user y master l'avance.

A un moment donné, je veux dev-user pour obtenir tous les commits faits dans master .

Comment dois-je m'y prendre ?

Je commence par le dossier racine de mon référentiel.

cd name_of_the_repository

puis

git checkout master 
git pull 
git checkout dev-user
git pull
git merge master 
git push 

J'espère que cela aidera quelqu'un d'autre dans la même situation.

0 votes

À partir de quel dossier exécutez-vous le git checkout master ? à partir du dossier branch ?

0 votes

@JoseCabreraZuniga, je le fais à partir du dossier racine de votre dépôt.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X