Corregir el historial de doble compromiso de git

Tuve que hacer funcionar git filter-branch el otro día. Seguí las instrucciones en github , pero algo salió mal. Creo que alguien en el equipo no ejecutó rebase en una sucursal local, y en su lugar fusionó los cambios. Desde entonces, el logging de commit está lleno de confirmaciones dobles, por ejemplo:

 commit b0c03ec925c0b97150594a99861d8f21fd3ab22d Author: XXX Date: Wed Mar 19 17:01:52 2014 -0400 Removed most clearfixs in templates commit f30c21d21b5ea715a99b0844793cb4b5f5df97a1 Author: XXX Date: Wed Mar 19 17:01:52 2014 -0400 Removed most clearfixs in templates commit 2346be43d0e02d3987331f0a9eeb2f12cd698ede Author: XXX Date: Wed Mar 19 16:40:26 2014 -0400 new networkingirect logic commit 1383070b31bde1aaa9eda7c2a9bcb598dd72247b Merge: d1e2eb6 94e07fe Author: XXX Date: Wed Mar 19 16:28:41 2014 -0400 Merge branch 'develop' of github.com:xxx/xxx into develop commit 79ce7824688cf2a71efd9ff82e3c7a71d53af229 Merge: 6079061 1ed3967 Author: XXX Date: Wed Mar 19 16:28:41 2014 -0400 Merge branch 'develop' of github.com:xxx/xxx into develop commit d1e2eb645a4fe2a1b3986082d0409b4075a0dbc9 Author: XXX Date: Wed Mar 19 16:28:36 2014 -0400 Fixed broken responsiveness for companies listing page and code refactoring. commit 6079061f6ef1f856f94d92bc0fdacf18854b8a89 Author: XXX Date: Wed Mar 19 16:28:36 2014 -0400 Fixed broken responsiveness for companies listing page and code refactoring. 

Curiosamente, no todos los commits están duplicates, como la "nueva lógica de networkingirección" más arriba. ¿Hay algo que pueda hacer para arreglar esto? Es relativamente benigno, pero ahora nuestro historial de commits parece una mierda. Esta publicación SO sugirió simplemente dejarla tal como está, pero prefiero tener un historial de compromiso limpio por el bien de la posteridad.

El command para lograr eso es:

 git rebase -i HEAD~7 

Esto abrirá su editor con algo como esto:

 pick f392171 Removed most clearfixs in templates pick ba9dd9a Removed most clearfixs in templates pick df71a27 Unew networkingirect logic pick 79ce782 Merge branch 'develop' of github.com:xxx/xxx into develop pick 1383070 Merge branch 'develop' of github.com:xxx/xxx into develop ... 

Ahora puedes decirle a Git qué hacer con cada commit. Mantengamos el compromiso f392171, aquel en el que agregamos nuestra function. Vamos a aplastar los siguientes dos commits en el primero, dejándonos con uno limpio.

Cambia tu file a esto:

 pick f392171 Removed most clearfixs in templates squash ba9dd9a Removed most clearfixs in templates pick df71a27 Unew networkingirect logic pick 79ce782 Merge branch 'develop' of github.com:xxx/xxx into develop squash 1383070 Merge branch 'develop' of github.com:xxx/xxx into develop 

Cuando guarda y sale del editor, Git aplica los dos cambios y luego lo regresa al editor para fusionar los tres posts de confirmación:

 # This is a combination of commits. # The first commit's message is: Removed most clearfixs in templates # This is the 2nd commit message: Removed most clearfixs in templates 

Cuando haya terminado, guarde y salga de su editor. Git aplastará los commits en uno. ¡Todo listo!

Entonces tienes que hacer

 git push origin your-branch -f 

para forzar su localmente comete cambios en la sucursal remota.

Nota: Tienes que hacer un squash para cada commit duplicado.

La respuesta de @VAIRIX es perfecta, pero hay casos complejos en los que las confirmaciones duplicadas no aparecen adyacentes entre sí, por lo que aplastarlas no será de ayuda.

Así que tomando la historia por debajo, (supongamos que ~ es el duplicado de a)

  # h # g # f # c~ # b~ # a~ # e # d # c # b # a 

Comando a seguir: (como se dice en la respuesta de @VAIRIX o debajo si quieres volver a establecer la base con el maestro) git rebase master -i (Mejor sigue git rebase -i HEAD~n para evitar el dolor de cabeza reescalado)

¡Ahora! 1) aplastar las confirmaciones repetidas de la siguiente manera:

  pick h pick g pick f pick c~ sb~ sa~ pick e pick d pick c pick b pick a 

Ahora, esto networkingucirá tus compromisos en c

  # h # g # f # c~ (having changes of a~ and b~) # e # d # c # b # a 

En mi caso, c ~ fue anti-commit de c, así que solo tuve que hacer el process nuevamente, pero ahora en vez de squash con s , estoy descartando el commit con d

  pick h pick g pick f dc~ (having changes of a~ and b~) pick e pick d pick c pick b pick a 

Ahora, tu historial eliminará todas las confirmaciones duplicadas. Ahora, puedes comparar con la twig de origen que tenías usando git diff que tenía commits duplicates contra tu esta twig. No debería haber ninguna diferencia si lo hiciste perfectamente.

Este process puede parecer un poco más largo, pero está seguro de que no se perdió ninguna confirmación.