git rebase para mantener la confirmación más reciente

He confirmado A, B, C y D y solo necesito mantener el más reciente, que es D. Veo que una de ellas es usar git rebase -i --root ya que puedes elegir y aplastar commits.

Aunque no entiendo tanto la diferencia entre pick y squash, me preguntaba que dado que los commits son incrementales, así commit D incluye todos los cambios intermedios, ¿por qué tienes que pasar por git rebase para mantener el commit más reciente y no solo eliminar el rest de las confirmaciones?

¿O me estoy perdiendo algo fundamental sobre git? ¿Puedes tener compromisos que no están relacionados entre sí? es decir, algún día usar commit B y en otra situación usar el commit D más reciente?

Los commit de git no son realmente incrementales, cada commit contiene todo el tree. Solo la interfaz de usuario presenta un compromiso en términos de diferencias con respecto a su elemento primario. En ese sentido, no tiene que pasar por git rebase para conservar la confirmación más reciente y descartar el rest, también puede usar el command git commit-tree plomería para crear la confirmación. El equivalente completo de la rebase sería una línea como esta:

 git reset --hard $(git commit-tree HEAD: -m message) 

Esa línea densa hace lo siguiente:

  • HEAD: refiere al object de tree contenido en la confirmación del encabezado actual.

  • git commit-tree TREE -m MESSAGE crea una nueva confirmación parentless que contiene el tree especificado, en nuestro caso el tree de HEAD . Su resultado es el SHA1 del compromiso recién creado.

  • git reset --hard COMMIT restablece la twig actual y el tree de trabajo a la confirmación especificada, en este caso la confirmación de raíz recién creada.

La creación de commits sin historial es desanimada por git porque tales commits dificultan que git opere con los datos. Los commands como git annotate y git merge dependen en gran medida de que la historia esté disponible, y sin esos git es una herramienta mucho less útil.