Disons que nous avons la situation suivante dans git:
Un référentiel créé:
mkdir GitTest2
cd GitTest2
git init
Certaines modifications dans le maître ont lieu et sont validées.
echo "On Master" > file
git commit -a -m "Initial commit"
Feature1 ramifié hors maître et certains travaux sont effectués:
git branch feature1
git checkout feature1
echo "Feature1" > featureFile
git commit -a -m "Commit for feature1"
Pendant ce temps, un bogue est découvert dans le code principal et une branche de correctif est établie
git checkout master
git branch hotfix1
git checkout hotfix1
Le bogue est corrigé dans la branche de correctif logiciel et fusionné dans le maître (peut-être après une révision de demande d'extraction/de code):
echo "Bugfix" > bugfixFile
git commit -a -m "Bugfix Commit"
git checkout master
git merge --no-ff hotfix1
Le développement sur feature1 continue:
git checkout feature1
Maintenant ma question: Dites que j'ai besoin du correctif dans ma branche de fonctionnalité, peut-être parce que le bogue s'y produit également. Comment y parvenir sans dupliquer les commits dans ma branche de fonctionnalités? Je veux éviter d’obtenir deux nouveaux commits sur ma branche de fonctionnalité qui n’ont aucun lien avec l’implémentation de la fonctionnalité. Cela semble particulièrement important pour moi si j'utilise des demandes d'extraction: toutes ces mises à jour seront également incluses dans la demande d'extraction et doivent être examinées bien que cela ait déjà été fait (car le correctif est déjà dans le maître).
Je ne peux pas faire un git merge master --ff-only
: "fatal: Impossible d'avancer rapidement, d'abandonner.", Mais je ne suis pas sûr que cela m'aide.
Vous devriez pouvoir rebaser votre branche sur master:
git checkout feature1
git rebase master
Gérer tous les conflits qui surviennent. Quand vous arriverez aux commits avec les corrections de bugs (déjà en 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 ensuite la rebase (en ignorant les commits déjà en master) avec
git rebase --skip
Si vous effectuez un git log
sur votre branche, vous verrez que la validation du correctif apparaîtra une seule fois et dans la partie principale.
Pour une discussion plus détaillée, consultez la documentation du livre Git sur git rebase
( https://git-scm.com/docs/git-rebase ) qui couvre exactement ce cas d'utilisation. .
================ Modifier 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 souhaite éviter les [...] commits sur ma branche de fonctionnalité qui n'ont aucun lien avec la mise en œuvre de la fonctionnalité.
Rebaser sa branche privée sur master est exactement ce qui donnera ce résultat. En revanche, fusionner le maître dans sa branche ferait précisément ce qu'il ne veut pas arriver : l'ajout d'un commit qui n'est pas lié à l'implémentation de la fonctionnalité sur laquelle il travaille via sa branche.
Pour adresser les utilisateurs qui lisent le titre de la question, ignorez le contenu et le contexte de la question, puis ne lisez que la première réponse à l'aveuglette, en supposant qu'il s'appliquera toujours à leur cas d'utilisation (différent), permettez-moi de préciser:
git merge master
comme dans la réponse de @ Sven).Enfin, si vous n'êtes pas satisfait du fait que cette réponse ne convient pas à votre situation, même si c'était pour @theomega, l'ajout d'un commentaire ci-dessous ne sera pas particulièrement utile: je ne contrôle pas la réponse sélectionnée, seul @theomega le fait.
Comment fusionner la branche principale dans la branche fonctionnelle? Facile:
git checkout feature1
git merge master
Il est inutile de forcer une fusion rapide vers l'avant ici, car cela ne peut pas être fait. Vous avez engagé à la fois la branche de fonctionnalité et la branche principale. L'avance rapide est impossible maintenant.
Regardez gitflow . C'est un modèle de branchement pour git qui peut être suivi, et vous l'avez déjà fait inconsciemment. C'est également une extension de git qui ajoute des commandes pour les nouvelles étapes du flux de travail qui effectuent automatiquement des tâches que vous auriez sinon besoin de faire manuellement.
Alors, qu'avez-vous fait dans votre flux de travail? Vous avez deux branches avec lesquelles travailler, votre branche feature1 est essentiellement la branche "develop" du modèle gitflow.
Vous avez créé une branche de correctif à partir de maître et l'avez fusionnée. Et maintenant tu es coincé.
Le modèle gitflow vous demande de fusionner également le correctif avec 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 toutes les modifications apportées à l'intérieur du correctif à la branche de fonctionnalité, mais UNIQUEMENT ces modifications. Ils peuvent entrer en conflit avec d'autres modifications de développement dans la branche, mais ils ne le seront pas avec la branche maître si vous fusionnez la branche d'objet en mode maître.
Soyez très prudent avec rebasing. Ne rebasez que si les modifications que vous avez apportées sont restées locales dans votre référentiel, par exemple. vous n'avez pas poussé de branches dans un autre référentiel. Rebaser est un excellent outil pour organiser vos commits locaux dans un ordre utile avant de le propager dans le monde, mais rebasonner ensuite gâchera les choses pour les git novices comme vous.
En vous basant sur cet article vous devriez:
créer une nouvelle branche basée sur la nouvelle version de master
git branch -b newmaster
fusionner votre ancienne branche avec une nouvelle
git checkout newmaster
résoudre les conflits sur la nouvelle branche de fonctionnalité
Les deux premières commandes peuvent être combinées à git checkout -b newmaster
De cette façon, votre historique reste clair car vous n'avez pas besoin de fusions en arrière. Et vous n'avez pas besoin d'être si prudent car vous n'avez pas besoin de git rebase
La réponse de Zimi décrit ce processus en général. Voici les détails:
1) Créez et basculez vers une nouvelle branche. Assurez-vous que la nouvelle branche est basée sur master
afin d’inclure les correctifs récents.
git checkout master
git branch feature1_new
git checkout feature1_new
# Or, combined into one command:
git checkout -b feature1_new master
2) Après avoir basculé vers la nouvelle branche, fusionnez les modifications de votre branche de fonctionnalité existante. Cela ajoutera vos commits sans dupliquer les commits de correctifs.
git merge feature1
3) Sur la nouvelle branche, résolvez les conflits éventuels entre votre fonction et la branche principale.
Terminé! Maintenant, utilisez la nouvelle branche pour continuer à développer votre fonctionnalité.
Voici un script que vous pouvez utiliser pour fusionner votre branche principale dans votre branche actuelle.
Le script effectue les opérations suivantes:
Enregistrez ce code sous forme de fichier de commandes (.bat) et placez le script n'importe où dans votre référentiel. Puis cliquez dessus pour le lancer et vous êtes prêt.
:: This batch file pulls current master and merges into current branch
@echo off
:: Option to use the batch file outside the repo and pass the repo path as an arg
set repoPath=%1
cd %repoPath%
FOR /F "tokens=*" %%g IN ('git rev-parse --abbrev-ref HEAD') do (SET currentBranch=%%g)
echo current branch is %currentBranch%
echo switching to master
git checkout master
echo.
echo pulling Origin master
git pull Origin master
echo.
echo switching back to %currentBranch%
git checkout %currentBranch%
echo.
echo attemting merge master into %currentBranch%
git merge master
echo.
echo script finished successfully
PAUSE
Vous pourrez peut-être effectuer un "tri sélectif" pour extraire les exacts commit (s) dont vous avez besoin dans votre branche de fonctionnalité.
Faites un git checkout hotfix1
pour accéder à la branche du correctif 1. Ensuite, faites un git log
pour obtenir le hachage SHA1 (grande séquence de lettres et de chiffres aléatoires identifiant de manière unique un commit) du commit en question. Copiez cela (ou les 10 premiers caractères environ).
Ensuite, git checkout feature1
pour revenir à votre branche de fonctionnalité.
Ensuite, git cherry-pick <the SHA1 hash that you just copied>
Cela entraînera cette validation et niquement cette validation dans votre branche de fonctionnalité. Ce changement sera dans la branche - vous venez de le "sélectionner". Ensuite, reprenez le travail, éditez, commettez, Push, etc. au contenu de votre coeur.
Lorsque, éventuellement, vous effectuez une autre fusion d'une branche dans votre branche de fonctionnalités (ou vice-versa), git reconnaîtra que vous avez déjà fusionné dans cette particularité commit, sachez que cela n'a pas été le cas. pour le faire à nouveau, et juste "sauter" sur elle.