git merge --squash

El botón squash de las interfaces web está bien, pero ¿cómo haríamos un squash desde la línea de comandos usando nuestro propio cliente de Git? El squash es un flag del comando git-merge, por lo que para hacer un squash tenemos que solicitar esta estrategia al realizar un merge.

Cuando trabajamos con Git, a menudo nos encontramos con la necesidad de fusionar una rama de desarrollo con la rama principal, pero sin querer que el historial se llene de múltiples commits intermedios que pueden dificultar la lectura y el mantenimiento. Aquí es donde entra en juego la estrategia de merge con squash, una técnica que nos permite combinar todos esos commits en uno solo, manteniendo un historial más limpio y organizado.

Imaginemos que tenemos una rama llamada Bootstrap5 que contiene varios commits con cambios realizados recientemente, y queremos integrar esos cambios en la rama principal, que llamaremos Trunk. Si hacemos un merge tradicional, Git simplemente moverá el puntero de la rama principal hacia adelante, integrando todos los commits tal cual, lo que puede generar un historial con muchos pasos intermedios. Esto es lo que se conoce como un merge con fast-forward cuando no hay divergencias.

Sin embargo, si queremos que todos esos commits se conviertan en uno solo, podemos usar el merge con squash. Lo que hace Git en este caso es tomar el conjunto completo de diferencias entre Trunk y Bootstrap5 y aplicarlas como un único cambio. Es como si hiciéramos un git diff Trunk...Bootstrap5 para ver todas las modificaciones acumuladas y luego aplicáramos ese diff de golpe sobre Trunk.

Para llevar a cabo este proceso, primero nos situamos en la rama donde queremos integrar los cambios, en este caso Trunk. Luego ejecutamos el comando:

git merge --squash Bootstrap5

Al hacer esto, Git nos mostrará un resumen de todos los cambios que se van a aplicar, pero no realizará el commit automáticamente. Esto es importante: el merge con squash no actualiza el puntero HEAD ni crea un commit por sí solo. En su lugar, deja todos los cambios preparados en el área de staging, listos para que nosotros decidamos cuándo y cómo confirmar esos cambios.

Podemos comprobar el estado con:

git status

y veremos que todos los archivos modificados están listos para ser confirmados. Ahora solo queda hacer el commit manualmente con:

git commit

Esto abrirá el editor de texto configurado para Git, que en muchos casos es Vim. Git nos mostrará un mensaje predefinido que incluye todos los mensajes de los commits originales que hemos aplastado. Sin embargo, la gracia del squash es precisamente ocultar esos detalles y dejar un mensaje limpio y claro. Por eso, es recomendable borrar ese texto y escribir un mensaje que resuma el cambio de forma concisa.

Si usamos Vim, podemos hacerlo de forma eficiente sin tener que borrar línea por línea con la tecla de borrar. Para ello, pulsamos Shift + V para entrar en modo visual por líneas, seleccionamos todas las líneas que queremos eliminar desplazándonos con las flechas o con Ctrl + D para bajar página a página, y luego pulsamos d para borrarlas. Después, con la tecla o en mayúscula podemos insertar el nuevo mensaje de commit. Finalmente, guardamos y salimos con :w y Enter.

Una vez hecho esto, si consultamos el historial con:

git log --oneline --graph --all

veremos que todos los commits que antes estaban en la rama Bootstrap5 han quedado condensados en un único commit en la rama Trunk. La rama original sigue existiendo, pero podemos eliminarla si ya no la necesitamos.

Este método es especialmente útil cuando queremos mantener un historial limpio y evitar que se vean todos los commits intermedios que hicimos durante el desarrollo, algo que a menudo ocurre cuando usamos interfaces web para hacer squash merges. Al hacerlo desde la consola, tenemos un control total sobre el proceso y podemos entender mejor qué está pasando detrás de escena.

Así, el merge con squash nos permite integrar cambios de forma ordenada, combinando múltiples commits en uno solo y facilitando la lectura y mantenimiento del historial de nuestro repositorio.

Lista de reproducción
  1. 1
    ¿Qué es Git?
    4 minutos
  2. 2
    Cómo instalar Git
    9 minutos
  3. 3
    Creando tu primer commit
    9 minutos
  4. 4
    Qué es el staging area
    10 minutos
  5. 5
    Cómo deshacer modificaciones de archivos
    7 minutos
  6. 6
    Cómo deshacer un commit con reset
    7 minutos
  7. 7
    Cómo revertir un commit con revert
    7 minutos
  8. 8
    Introducción a las ramas
    6 minutos
  9. 9
    Cómo crear y modificar ramas
    6 minutos
  10. 10
    Commits bajo el workflow Feature Branch
    6 minutos
  11. 11
    Cómo fusionar ramas con merge
    6 minutos
  12. 12
    Fusiones conflictivas
    9 minutos
  13. 13
    Cómo construir alias
    7 minutos
  14. 14
    Más sobre conflictos
    9 minutos
  15. 15
    Etiquetas
    7 minutos
  16. 16
    Tags anotados
    9 minutos
  17. 17
    git stash: esconder cambios
    6 minutos
  18. 18
    Introducción a remotos
    5 minutos
  19. 19
    Pusheando a un remoto
    6 minutos
  20. 20
    Clonando y haciendo pull
    6 minutos
  21. 21
    Fetch y pull rebases
    8 minutos
  22. 22
    Rebase
    7 minutos
  23. 23
    Rebase interactivo
    6 minutos
  24. 24
    Master, main y otros nombres de rama
    9 minutos
  25. 25
    git switch
    9 minutos
  26. 26
    git-restore
    10 minutos
  27. 27
    git-grep
    11 minutos
  28. 28
    Gitignore
    11 minutos
  29. 29
    El flag --patch
    9 minutos
  30. 30
    git-apply y parches en bruto (advanced)
    9 minutos
  31. 31
    Merge octopus (advanced)
    9 minutos
  32. 32
    Conventional commits
    12 minutos
  33. 33
    Merge and squash (GitLab / GitHub...)
    6 minutos
  34. 34
    git merge --squash
    7 minutos
  35. 35
    git-bisect
    8 minutos
  36. 36
    git-blame
    6 minutos
  37. 37
    git-reflog
    10 minutos
  38. 38
    Git para la Bash
    11 minutos
  39. 39
    Submódulos (parte 1)
    7 minutos
  40. 40
    Submódulos (parte 2)
    10 minutos
  41. 41
    Otros clientes Git (último episodio)
    9 minutos