Comment diviser le dernier commit en deux dans Git
J'ai deux branches, maître et forum et j'ai juste fait quelques modifications dans forum branche, que je tiens à piocher dans maître. Mais malheureusement, la validation, je veux cherry-pick contient également quelques modifications que je ne veux pas.
La solution serait probablement d'une certaine manière de suppression erronée de s'engager et de le remplacer par deux des livraisons séparées, l'une avec les modifications que je veux choisir en master, et d'autres qui ne leur appartient pas.
J'ai essayé de faire
git reset --hard HEAD^
supprimé tous les changements, j'ai donc dû revenir avec
git reset ORIG_HEAD
Donc ma question est, quelle est la meilleure façon de split dernier commit en deux s'engage?
Vous devez vous connecter pour publier un commentaire.
Vous devez utiliser l'index. Après avoir fait un mixte de réinitialisation ("git reset TÊTE^"), ajouter
la première série de changements dans l'index, puis les valider. Puis engagez-le
le repos.
Vous pouvez utiliser "git add" pour mettre toutes les modifications apportées à un fichier à l'index. Si vous
ne voulez pas de mettre en scène chaque modification apportée à un fichier, seulement certains d'entre eux, vous
pouvez utilisez "git add -p".
Voyons un exemple. Supposons que j'avais un fichier nommé monfichier, qui contient
le texte suivant:
Je l'ai modifié dans mon dernier commit de sorte que maintenant il ressemble à ceci:
Maintenant, je décide que je veux la couper en deux, et je veux l'insertion de la
première ligne à être dans le premier commit, et l'insertion de la dernière ligne à
dans la deuxième commettre.
J'ai d'abord revenir à la TÊTE de la mère, mais je veux garder les modifications dans le système de fichiers,
j'ai donc utilisez "git reset" sans argument (qui va faire un soi-disant "mixte"
réinitialiser):
Maintenant je utilisez "git add -p" pour ajouter les modifications que je veux commettre à l'index (=je
stade de mer). "git add -p" est un outil interactif qui vous interroge au sujet de ce que
les modifications apportées au fichier faut-il ajouter à l'index.
Puis-je commettre ce premier changement:
Maintenant, je peux commettre tous les autres changements (à savoir le chiffre "2" mettre dans la dernière ligne):
Nous allons consulter le journal pour voir ce qui s'engage, nous avons:
git reset [--patch|-p] <commit>
que vous pouvez utiliser pour vous épargner la peine d'avoir àgit add -p
après la réinitialisation. Suis-je le droit? À l'aide de git 1.7.9.5.Objectifs:
splitme
) en deux.Plan:
splitme
.splitme
.Le rebase étapes (1 & 7) peut être ignorée si l'
splitme
est la plus récente s'engager.Si je voulais le diviser les fichiers pour être la première engagée, alors je dirais rebase -i nouveau et changer l'ordre
git reset HEAD^
était la pièce manquante du puzzle. Fonctionne bien avec-p
trop. Merci!-- $files
argumentgit reset
. Avec les chemins de passé,git reset
restaure les fichiers à l'état de référence s'engager mais ne changera s'engage. Si vous le laissez à l'extérieur des sentiers, puis vous "perdre" le commit que vous voulez modifier dans la prochaine étape.git reset HEAD^ -- .
. Très étonnamment, c'est pas exactement le comportement degit reset HEAD^
.À changer le cours s'engager dans deux commits, vous pouvez faire quelque chose comme ce qui suit.
Soit:
Cela permet d'annuler le dernier commit, mais laisse tout mis en scène. Vous pouvez ensuite unstage certains fichiers:
Éventuellement restage parties de ces fichiers:
Faire un nouveau premier commit:
La scène et de commettre le reste des modifications dans un deuxième commit:
Ou:
Annuler et unstage tous les changements survenus depuis le dernier commit:
Sélectivement stade de la première série de changements:
Commettre:
Commettre le reste de l'changements:
(Dans une autre étape, si vous aviez annulé un commit que l'ajout d'un nouveau fichier et que vous souhaitez ajouter à la deuxième commit, vous devrez ajouter manuellement comme
commit -a
seulement les étapes des changements de suivi des dossiers.)Exécuter
git gui
, sélectionnez l'option "Modifier le dernier commit" bouton radio, et unstage (Commit > Unstage De Commettre, ou Ctrl-U) les modifications que vous ne voulez pas aller en premier commit. Je pense que c'est la meilleure façon d'aller à ce sujet.Une autre chose que vous pourriez faire est de choisir le changement sans commettre (
git cherry-pick -n
) et puis, que ce soit manuellement ou avecgit gui
sélectionnez les changements souhaités avant de s'engager.le-hard est ce qui tue vos modifications.
Je suis surpris que personne n'a suggéré
git cherry-pick -n forum
. Cela mettra en scène les changements de la dernièreforum
s'engager, mais pas commettre eux - vous pouvez ensuitereset
loin les changements que vous n'avez pas besoin et de s'engager à ce que vous souhaitez conserver.Le double-revenir-squash méthode
git checkout HEAD~1 -- files with unwanted changes
etgit commit
. Si non, les fichiers avec un mélange de changements peuvent être partiellement mises en scènegit reset file
etgit add -p file
comme une étape intermédiaire.) Appelons cela le revenir.git revert HEAD
– Faire encore un autre de commettre, qui ajoute le dos les changements non désirés. C'est le double-revenirgit rebase -i HEAD~3
). Ce commit devient maintenant libre de changements non désirés, pour ceux qui sont dans la deuxième commettre.Avantages
Puisque vous êtes cherry-picking, vous pouvez:
cherry-pick
avec--no-commit
ajout de l'option.reset
et l'utilisationadd --patch
,add --edit
ou tout simplementadd
à la scène que vous souhaitez conserver.commit
la mise en scène des changements.--reuse-message=<old-commit-ref>
ou--reedit-message=<old-commit-ref>
options pour lacommit
commande.reset --hard
.Une autre façon, la préservation ou de l'édition de l'original message de commit:
cherry-pick
l'original s'engager comme d'habitude.add
à l'étape de la reprise.commit --amend
à l'effet de la reprise sur la cerise cueillies à la commettre.Cela pourrait être une autre solution ciblée pour les cas où il y a une énorme s'engager et d'une petite quantité de fichiers doit être déplacé dans un nouveau commit. Cela ne fonctionnera que si un ensemble de
<path>
fichiers doivent être extraits de le dernier commit à la TÊTE et tous déplacé vers un nouveau commit. Si plusieurs commits sont nécessaires, les autres solutions peuvent être utilisées.D'abord faire des pièces dans la mise en scène et unstaged secteurs qui contiennent les modifications pour revenir le code avant la modification et après la modification respectivement:
Pour comprendre ce qui va se passer (flèche et les commentaires ne font pas partie de la commande):
Revenir
<path>
changements dans le dernier commit:Créer de nouveaux engager avec
<path>
changements:Ce qui a pour effet de créer un nouveau commit qui contient les modifications extrait du dernier commit.