Borrando Huellas: Elimina Información Sensible de tu Historial de Commits con Git Rebase

Ivano García
5 min readJul 4, 2023

--

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 commit
  • reword: usar commit pero editar el mensaje del commit
  • edit: usar commit pero detenerse para editar
  • squash: usar commit pero combinarlo con el commit anterior
  • fixup: igual que "squash", pero descartar la información de este commit
  • exec: 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.

--

--

Ivano García

Systems engineer at @adidas, Blockchain developer, technology and innovation lover