¿Cómo eliminar commits duplicates después de usar git filter-branch?

Utilicé el código a continuación para editar mi historial de confirmaciones, un correo electrónico incorrecto se configuró en mi configuration de git y quise actualizar todas mis confirmaciones con la correcta.

git filter-branch --env-filter ' WRONG_EMAIL="xxx" NEW_NAME="xxx" NEW_EMAIL="xxxx" if [ "$GIT_COMMITTER_EMAIL" = "$WRONG_EMAIL" ] then export GIT_COMMITTER_NAME="$NEW_NAME" export GIT_COMMITTER_EMAIL="$NEW_EMAIL" fi if [ "$GIT_AUTHOR_EMAIL" = "$WRONG_EMAIL" ] then export GIT_AUTHOR_NAME="$NEW_NAME" export GIT_AUTHOR_EMAIL="$NEW_EMAIL" fi ' --tag-name-filter cat -- --branches --tags 

ahora el problema es que duplicó todos los commits, incluso los que no son míos, entendería que dejó mis viejos commits y creó uno nuevo, pero ¿por qué duplicó los commits que no son míos? ¿Alguien podría decirme por qué sucedió esto y cómo solucionarlo?

Creo que el problema es que te perdiste haciendo lo siguiente

git push --force --tags origin 'refs/heads/*'

Después de cambiar las confirmaciones localmente, debe forzar la actualización en su control remoto.

El duplicado se debe principalmente a que los compromisos anteriores en su control remoto no cambiaron.

Bueno, se necesita un pequeño trasbackground semi-técnico para entender completamente esto …

tl; dr : si se reescribe un compromiso, entonces todos los hijos de ese compromiso también deben reescribirse. Entonces, por ejemplo, parece que tienes que reescribir la confirmación inicial; eso forzaría la reescritura de cada compromiso. No puedes arreglarlo; esto es parte integral de cómo funciona git. Si desea cambiar el contenido en la confirmación raíz, cambie el valor de hash para cada confirmación, ineludiblemente.

Detalles :

La estructura dentro de un git repo es bastante rígida; esto tiene que ver con la forma en que git logra su performance, usando hashes para comparaciones rápidas de contenido, etc. Cada object recibe un valor hash, y ese valor hash se usa para almacenar el object. Esto se aplica a los files (llamados objects blob), directorys (objects de tree), confirmaciones (los objects que le preocupan) y cualquier otra cosa que git pueda almacenar y abordar.

Un algorithm estricto calcula el hash, por lo que al mismo contenido siempre se le asignará el mismo hash. De nuevo, esto es parte integral de cómo Git cambia la detección (entre otras cosas). Por el contrario, es extraordinariamente poco probable que dos objects diferentes obtengan el mismo valor hash (y si lo hicieran, dañaría su repository).

Por lo tanto, todas las cosas que hacen que un object sea "igual que" o "diferente de" otro object deben tenerse en count al calcular el hash de ese object. En el caso de una confirmación, CommitA y CommitB podrían ser idénticos en todos los sentidos, excepto que CommitA es hijo de CommitX y CommitB es hijo de CommitY. Tendrían que tratarse como objects diferentes o nunca podría atravesar adecuadamente la historia.

Entonces cuando reescribes el padre de Commit D, cambias el hash padre que identifica el lugar de Commit D en la historia, y por lo tanto debes reescribir Commit D (dándole también un nuevo hash … y esto continúa recursivamente a través de todos los commit de descendientes).