J'ai fait quelques changements dans ma branche principale et je veux les apporter en amont. quand je sélectionne les commits suivants, je reste bloqué sur fd9f578 où git dit:
$ git cherry-pick fd9f578
fatal: Commit fd9f57850f6b94b7906e5bbe51a0d75bf638c74d is a merge but no -m option was given.
Qu'est-ce que Git essaie de me dire et est-ce que c'est la bonne chose à utiliser ici? La branche principale inclut des changements aux fichiers qui ont été modifiés dans la branche en amont, donc je suis sûr qu'il y aura des conflits de fusion mais ceux-ci ne sont pas trop mauvais à redresser. Je sais quels changements sont nécessaires où.
Ce sont les engagements que je veux apporter en amont.
e7d4cff added some comments...
23e6d2a moved static strings...
44cc65a incorporated test ...
40b83d5 whoops delete whitspace...
24f8a50 implemented global.c...
43651c3 cleaned up ...
068b2fe cleaned up version.c ...
fd9f578 Merge branch 'master' of ssh://extgit/git/sessions_common
4172caa cleaned up comments in sessions.c ...
la source
git rebase
- c'est comme une fusion, mais au lieu d'intégrer deux branches, il transplante l'une pour s'asseoir au-dessus de l'autre.git show
et similaires).git reset --hard HEAD@{1}
pour récupérer votre commit manquant.git reset
ne se limite pas à reculer "dans l'histoire".git checkout -b mybranch HEAD@{1}
fonctionnerait également.git merge
peut avoir des conséquences imprévues. Cette commande ajoutera toutes les autres validations (plus anciennes) qui existent sur la branche parent. Habituellement, les gens choisissent de choisir parce qu'ils ne veulent pas que les autres commettent. Assurez-vous de vérifier que vous n'implémentez que les modifications que vous souhaitez!-m
signifie le numéro de parent.Du git doc:
Par exemple, si votre arbre de validation est comme ci-dessous:
puis
git cherry-pick E
produira la question que vous face.git cherry-pick E -m 1
signifie utiliserD-E
, tout engit cherry-pick E -m 2
utilisantB-C-E
.la source
@ La réponse de Borealid est correcte, mais supposez que vous ne vous souciez pas de conserver l'historique de fusion exact d'une branche et que vous souhaitiez simplement en sélectionner une version linéarisée. Voici un moyen simple et sûr de le faire:
État de départ: vous êtes sur une branche
X
et vous souhaitez sélectionner les commitsY..Z
.git checkout -b tempZ Z
git rebase Y
git checkout -b newX X
git cherry-pick Y..tempZ
git branch -D tempZ
Ce que cela fait, c'est de créer une branche
tempZ
basée surZ
, mais avec l'historique àY
partir de la linéarisation, puis de la sélectionner sur une copie deX
appelénewX
. (Il est plus sûr de le faire sur une nouvelle branche plutôt que de muterX
.) Bien sûr, il peut y avoir des conflits à l'étape 4, que vous devrez résoudre de la manière habituelle (cherry-pick
fonctionne très bienrebase
à cet égard). Enfin, il supprime latempZ
branche temporaire .Si l'étape 2 donne le message "La branche actuelle tempZ est à jour", alors elle
Y..Z
était déjà linéaire, alors ignorez simplement ce message et passez aux étapes 3 suivantes.Ensuite, vérifiez
newX
et voyez si cela a fait ce que vous vouliez.(Remarque: ce n'est pas la même chose qu'un simple
git rebase X
sur une brancheZ
, car cela ne dépend en aucune façon de la relation entreX
etY
; il peut y avoir des commits entre l'ancêtre commun et ceY
que vous ne vouliez pas.)la source
git rebase Y
ditCurrent branch tempZ is up to date
Y..Z
c'était déjà linéaire. Vous pouvez donc ignorer ce message et passer aux étapes 3 et 4.Simplifier. Choisissez les commits. Ne choisissez pas la fusion.
Voici une réécriture de la réponse acceptée qui clarifie idéalement les avantages / risques des approches possibles:
Vous essayez de choisir le fd9f578, qui était une fusion avec deux parents.
Au lieu de sélectionner une fusion par cerise, la chose la plus simple est de sélectionner par cerise le ou les commit (s) que vous voulez réellement de chaque branche de la fusion.
Puisque vous avez déjà fusionné, il est probable que tous les commits souhaités figurent dans votre liste. Choisissez-les directement et vous n'avez pas besoin de jouer avec le commit de fusion.
explication
La façon dont fonctionne une sélection de cerises consiste à prendre le diff que représente un ensemble de modifications (la différence entre l'arbre de travail à ce point et l'arbre de travail de son parent) et à appliquer l'ensemble de modifications à votre branche actuelle.
Si une validation a deux parents ou plus, comme c'est le cas avec une fusion, cette validation représente également deux différences ou plus. L'erreur se produit en raison de l'incertitude sur laquelle diff devrait s'appliquer.
alternatives
Si vous déterminez que vous devez inclure la fusion par rapport à la sélection des validations associées, vous avez deux options:
(Plus compliqué et obscur; jette également l'historique), vous pouvez indiquer quel parent doit appliquer.
Utilisez l'
-m
option pour le faire. Par exemple,git cherry-pick -m 1 fd9f578
utilisera le premier parent répertorié dans la fusion comme base.Considérez également que lorsque vous choisissez un commit de fusion, il réduit toutes les modifications apportées dans le parent que vous n'avez pas spécifié
-m
dans ce commit . Vous perdez toute leur histoire et glomez tous leurs différends. Ton appel.(Plus simple et plus familier; conserve l'historique), vous pouvez utiliser à la
git merge
place degit cherry-pick
.git merge
, il essaiera d'appliquer toutes les validations qui existent sur la branche que vous fusionnez, et les listera individuellement dans votre journal git.la source
Simplification de la méthode @Daira Hopwood idéale pour choisir un seul commit. Pas besoin de branches temporaires.
Dans le cas de l'auteur:
alors fais:
la source