Vous pouvez exécuter git rebase --interactive
et réorganiser D avant B et écraser D en A.
Git ouvrira un éditeur et vous verrez un fichier comme celui-ci, ex: git rebase --interactive HEAD~4
pick aaaaaaa Commit A
pick bbbbbbb Commit B
pick ccccccc Commit C
pick ddddddd Commit D
# Rebase aaaaaaa..ddddddd onto 1234567 (4 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
Maintenant, vous modifiez le fichier qui ressemble à ceci:
pick aaaaaaa Commit A
squash ddddddd Commit D
pick bbbbbbb Commit B
pick ccccccc Commit C
Et git va maintenant fusionner les changements de A et D en un seul commit, et mettre B et C ensuite. Lorsque vous ne souhaitez pas conserver le message de validation de D, au lieu de squash
, vous utilisez le fixup
mot - clé. Pour en savoir plus fixup
, vous pouvez consulter la git rebase
documentation ou consulter cette question qui a de bonnes réponses.
There is no tracking information for the current branch
erreur lors du rebasage. Dans ce cas , vous devez spécifier le nombre de commits que vous voulez travailler avec, comme ceci:git rebase -i HEAD~4
. Voyez cette réponse .Remarque: vous ne devez en aucun cas modifier les commits qui ont été transférés vers un autre dépôt, sauf si vous en connaissez les conséquences .
git log --oneline -4
git rebase --interactive
Type
i
(Mettre VIM en mode insertion)Modifiez la liste pour qu'elle ressemble à ceci (vous n'avez pas à supprimer ou à inclure le message de validation). Ne vous trompez pas
squash
! :Tapez Escensuite
ZZ
(Enregistrer et quitter VIM)Type
i
Remplacez le texte par ce à quoi vous voulez que le nouveau message de validation ressemble. Je recommande que ce soit une description des changements dans commit
A
etD
:Tapez Escalors
ZZ
git log --oneline -4
git show E
Vous avez maintenant créé un nouveau commit
E
. S'engageA
etD
ne font plus partie de votre histoire mais ne sont pas partis. Vous pouvez toujours les récupérer à ce stade et pendant un certain tempsgit rebase --hard D
(git rebase --hard
détruira toutes les modifications locales! ).la source
Pour ceux qui utilisent SourceTree :
Assurez-vous que vous n'avez pas déjà poussé les validations.
Squash with previous
la source
Le rebase interactif fonctionne bien jusqu'à ce que vous ayez une grande branche de fonctionnalités avec 20-30 commits et / ou quelques fusions du maître ou / et corrigeant les conflits pendant que vous vous engagiez dans votre branche. Même avec trouver mes engagements à travers l'histoire et remplacer
pick
parsquash
ne fonctionne pas ici. Alors je cherchais un autre moyen et j'ai trouvé cet article . J'ai fait mes modifications pour travailler ceci sur une branche séparée:Avant cela, j'ai reçu ma pull request avec environ 30 commits avec 2-3 fusions de master + résolution des conflits. Et après cela, j'ai obtenu des relations publiques claires avec un seul commit.
PS voici un script bash pour effectuer ces étapes en mode automatique.
la source
$ git checkout master
$ git log --oneline
$ git rebase --onto HEAD ^^^ HEAD ^
$ git log --oneline
la source
--oneline
? Et il semble que vous ayez abandonnéC
etB
, ce n'est pas ce que le PO avait l'intention.git show A
) et D, C et B ont été perdus dans mon ref-log. J'ai dûgit rebase D
rentrer.