Borrando Huellas: Elimina Información Sensible de tu Historial de Commits con Git Rebase
A lo largo de nuestra carrera se nos han presentado diferentes problemáticas e incluso soluciones que de una forma u otra nos ayuda a aprender, más allá de un curso o un tutorial. Es acá en donde nuestro aprendizaje gira entorno a la experiencia.
No es un secreto que nosotros los desarrolladores usamos repositorios para mantener nuestro código (nuestros proyectos) a salvo, acá aplicamos el famoso Git y sus grandes ventajas.
¿Qué es Git?
Git es una herramienta de control de versiones distribuido, creada por Linus Torvalds, que permite a los desarrolladores realizar un seguimiento de los cambios en los archivos de un proyecto a lo largo del tiempo. Este seguimiento incluye cambios en el contenido del archivo, quién hizo el cambio, cuándo se hizo y por qué.
Sin embargo Git va mas allá de eso por lo que nos centraremos en uno de sus comandos que en mi opinión se vuelve muy poderoso. Git Rebase
¿Qué es Git Rebase?
Git rebase es una poderosa herramienta que “reaplica” tus cambios sobre otra base. Puede ser usado para hacer que tu rama parezca que se desarrolló directamente a partir del último commit de la rama que estás intentando fusionar, dando una historia de commits mucho más limpia.
El comando git rebase
permite integrar los cambios de una rama a otra y también alterar los commits de una manera avanzada. Con git rebase
, puedes cambiar el orden de los commits, modificar sus mensajes, combinarlos, y mucho más.
¿Cómo podemos aplicar Git Rebase?
Un caso común es cuando estás trabajando en una rama (my_branch
) y alguien ha hecho commits en la rama main
que te gustaría tener. Para ello, haces:
git checkout my_branch
git rebase main
Esto tomará todos tus cambios en my_branch
y los "reaplicará" sobre los cambios hechos en main
.
Ahora que sabemos esto planteemos el siguiente problema:
El Problema
Imagina que tienes una rama con varios commits. Los commits se ven así:
a1b2c3d First commit with sensible data
e4f5g6h Second commit
i7j8k9l Third commit
En el primer commit (a1b2c3d
), subiste un archivo con información sensible y privada, pero luego te diste cuenta de tu error y eliminaste el archivo en un commit posterior. Sin embargo, el problema es que el archivo aún aparece en el historial de Git, lo cual es un riesgo para la seguridad.
La Solución: Git Rebase Interactivo
Para resolver esto, usaremos git rebase -i --root
(importante señalar que al utilizar el comando — root
te mostrará todos los commits desde el origen). Esto abre un editor con una lista de todos los commits desde el principio hasta el actual. Ahora, podemos decidir qué hacer con cada commit. Algunas de las opciones son:
pick
: usar commitreword
: usar commit pero editar el mensaje del commitedit
: usar commit pero detenerse para editarsquash
: usar commit pero combinarlo con el commit anteriorfixup
: igual que "squash", pero descartar la información de este commitexec
: ejecutar un comando usando el contenido de este commit
En nuestro caso, queremos editar el primer commit (a1b2c3d
), por lo que cambiamos pick
por edit
(o e
):
edit a1b2c3d First commit with sensible data
pick e4f5g6h Second commit
pick i7j8k9l Third commit
Esto por lo general abre a vim como editor de terminal, para insertar o editar debes presionarl la tecla “I” y esto te permitirá escribir, para salir presionamos “ESC” y finalmente escribir y guardar escribiendo wq
Después de guardar y cerrar el editor , Git te lleva a ese commit. Aquí, puedes hacer los cambios necesarios, como git rm private_file
y luego hacemos un commit de este cambio:
git commit --amend
git commit --amend
cambiará el commit que estamos editando, en lugar de crear uno nuevo.
Para continuar con el rebase, ejecutamos git rebase --continue
.
Esto te llevará a través de cada commit subsiguiente, aplicándolo en la cima del cambio que acabas de hacer. Si en algún punto te encuentras con conflictos, Git te lo dirá y podrás resolverlos antes de continuar.
Otro comando de gran ayuda: Git Squash
El comando squash
en git rebase -i
permite combinar un commit con el anterior en un solo commit.
Si marcamos un commit con squash
durante un rebase interactivo, Git combinará ese commit con el commit anterior en un solo commit. A diferencia de edit
, squash
no detiene el proceso de rebase para que puedas hacer cambios. En cambio, combina automáticamente los cambios de ambos commits y luego te permite editar el mensaje del commit para el nuevo commit combinado.
Por ejemplo, considera la siguiente lista de commits en un rebase interactivo:
pick a1b2c3d First commit with sensible data
pick e4f5g6h Second commit
squash i7j8k9l Third commit
Esto tomará el “Tercer commit” y lo combinará con el “Segundo commit” en un solo commit. El resultado final será que tu historial de commits parecerá que sólo has hecho dos commits en lugar de tres.
Sobre git push --force
Ya estamos a un solo paso de nuestra solución.
Una vez que hayas realizado cambios en tu rama local con rebase
, deberás hacer un push forzado (git push origin my_branch --force
) para aplicar estos cambios en el repositorio remoto.
Si la rama ya existe y no puede ser eliminada, necesitarás aplicar este comando. Pero si es tu rama personal, puedes eliminarla del repositorio remoto y luego hacer un nuevo push.
Consideraciones y Advertencias
Manipular la historia con git rebase
es potente, pero también puede ser peligroso. Es posible perder commits si algo sale mal, así que siempre es una buena idea tener una copia de seguridad. Además, un push forzado puede causar problemas si otros están trabajando en la misma rama.
Recuerda: ¡Un gran poder conyeva a una gran responsabilidad!
Con estas herramientas, tendrás más control sobre tu repositorio Git y podrás solucionar problemas comunes con elegancia y eficiencia.