@Mark Longair l'a cloué dans sa réponse ici , mais j'aimerais ajouter quelques informations supplémentaires.
Associé, et répondre à la question de savoir comment diviser une grande demande de tirage (PR), en particulier lorsque l'écrasement de vos validations est impossible en raison d'une ou plusieurs fusions de master dans votre feature_branch
Ma situation:
j'ai fait un gros feature_branch
avec 30 commits et ouvert une Pull Request (PR) sur GitHub pour la fusionner master
. La branche a master
changé une tonne sous moi et a reçu 200 commits que je feature_branch
n'avais pas. Pour résoudre les conflits que j'ai faits git checkout feature_branch
et git merge master
pour fusionner master
les modifications apportées à mon feature_branch
. J'ai choisi merge
plutôt que rebase
sur le dernier maître, donc je devrais résoudre les conflits une seule fois au lieu de potentiellement 30 fois (une fois pour chacun de mes commits). Je ne voulais pas écraser mes 30 commits en 1 d'abord, puis rebaser sur le derniermaster
car cela pourrait effacer l'historique des commentaires sur GitHub dans le PR. Donc, j'ai fusionné master dans ma branche de fonctionnalités et résolu les conflits une seule fois. Tout allait bien. Mon PR, cependant, était trop gros pour que mes collègues puissent l'examiner. J'avais besoin de le diviser. Je suis allé écraser mes 30 commits et OH NON! OÙ SONT-ELLES? ILS SONT TOUS INTERMÉLANGÉS AVEC master
les 200 commits récents maintenant parce que j'ai fusionné master
dans mon feature_branch
! QUE FAIS-JE?
git cherry
utilisation au cas où vous voudriez essayer git cherry-pick
des commits individuels:
git cherry
à la rescousse (en quelque sorte)!
Pour voir tous les commits qui sont dans feature_branch
mais PAS dans, master
je peux faire:
git checkout feature_branch
git cherry master
OU, je peux vérifier les commits de N'IMPORTE QUELLE branche sans m'assurer que je suis le feature_branch
premier en faisant git cherry [upstream_branch] [feature_branch]
, comme ceci. Encore une fois, cela vérifie pour voir quels commits SONT dans feature_branch
mais ne sont PAS dans upstream_branch
( master
dans ce cas):
git cherry master feature_branch
L'ajout -v
montre également les lignes d'objet du message de validation:
git cherry -v master
La redirection vers "word count" "-lines" ( wc -l
) compte le nombre de commits:
git cherry master | wc -l
Vous pouvez comparer ce nombre au numéro de validation indiqué dans votre PR GithHub pour vous sentir mieux en sachant que git cherry
cela fonctionne vraiment. Vous pouvez également comparer les hachages git un par un et voir qu'ils correspondent entre git cherry
et GitHub. Notez que git cherry
ne compteront pas tous les commits de fusion où vous avez reportés master
dans feature_branch
, mais GitHub. Donc, si vous voyez une petite différence dans le décompte, recherchez le mot "fusion" sur la page de validation de GitHub PR et vous verrez probablement que c'est le coupable qui n'apparaît pas git cherry
. Ex: un commit intitulé "Fusionner la branche 'master' dans feature_branch" apparaîtra dans le GitHub PR mais pas lors de l'exécution git cherry master feature_branch
. C'est bien et attendu.
Donc, maintenant j'ai un moyen de savoir quels diffs je pourrais vouloir choisir une nouvelle branche de fonctionnalités pour diviser ce diff: je peux utiliser git cherry master feature_branch
localement, ou regarder les commits dans le GitHub PR.
Comment l'écrasement pourrait aider - si seulement nous pouvions écraser:
Une alternative, cependant, pour diviser mon gros diff est d' écraser tous mes 30 commits en un seul, de les patcher sur une nouvelle branche de fonctionnalité, de réinitialiser le commit du correctif, puis de l'utiliser git gui
pour ajouter des morceaux fichier par fichier, morceau par morceau, ou ligne par ligne. Une fois que j'ai une sous-fonctionnalité, je peux valider ce que j'ai ajouté puis vérifier une nouvelle branche, en ajouter d'autres, valider, vérifier une nouvelle branche, etc., jusqu'à ce que ma grande fonctionnalité soit divisée en plusieurs sous-fonctionnalités . Le problème est que mes 30 commits sont mélangés avec les 200 autres commits d'autres personnes en raison de mon git merge master
dans mon feature_branch
, donc le rebasage est donc peu pratique, car je devrais passer au crible 230 commits pour réorganiser et écraser mes 30 commits.
Comment utiliser un fichier de correctif comme remplacement beaucoup plus facile de l'écrasement:
Une solution consiste simplement à obtenir un fichier de correctif contenant un «équivalent squash» de mes 30 commits, à le patcher sur un nouveau fork de master
(une nouvelle sous-branche de fonctionnalité) et à travailler à partir de là, comme suit:
git checkout feature_branch
# ensure I have the latest changes from master merged into feature_branch
git merge master
# Obtain a patch file, which is the equivalent of a squash of my 30 commits into 1 commit:
git diff master..feature_branch > ~/mypatch.patch
git checkout master
# Create a new, sub-feature branch
git checkout -b feature_branch2
# Patch the 30 commit patch file onto it:
git apply ~/mypatch.patch
Maintenant, mon correctif de 30 commit est appliqué localement, mais non mis en scène et non validé.
Maintenant, utilisez git gui
pour ajouter des fichiers, des morceaux et / ou des lignes et briser votre gros PR ou "diff":
Notez que si vous ne l'avez pas git gui
, vous pouvez facilement l'installer dans Ubuntu avec sudo apt install git-gui
.
Je peux maintenant exécuter git gui
et commencer à ajouter des fichiers, des morceaux et / ou des lignes (en cliquant avec le bouton droit dans le programme git GUI), et diviser la branche de 30 fonctionnalités de validation en sous-branches comme décrit ci-dessus, en ajoutant, en validant, puis en forçant à plusieurs reprises une nouvelle branche de fonctionnalité et répéter ce cycle jusqu'à ce que toutes les modifications aient été ajoutées à une sous-branche de fonctionnalité et que ma fonctionnalité 30-commit soit divisée avec succès en 3 ou 4 sous-fonctionnalités. Je peux maintenant ouvrir un PR distinct pour chacune de ces sous-fonctionnalités, et elles seront plus faciles à examiner pour mon équipe.
Références:
- Créez un fichier correctif ou diff à partir du référentiel git et appliquez-le à un autre référentiel git différent