reset, rebase y cherry-pick son distintas formas que nos ofrece git para borrar nuestros commits. Cada una con su peculiaridad.
Aunque no está bien visto ya que estamos «borrando la historia», puede ocurrir que queramos borrar varios commits que hemos hecho en algún momento y hemos subido al repositorio.
Índice:
log ficticio para los ejemplos
Para los ejemplos, vamos a utilizar el siguiente árbol de commits:
Número |
Hash |
Mensaje |
1 |
8c2aafb |
Bug de javascript |
2 |
be54fcb |
Cambios en la interfaz |
3 |
22bb985 |
Actualizar base de datos |
4 |
6c3813c |
Bug en la creación de pedidos |
5 |
a3d37d5 |
Añadir bundle de usuarios |
6 |
741aabb |
Incluir librería PDF |
7 |
a479739 |
Añadir proyecto a git |
git reset
Si se trata de borrar el último commit que hemos hecho lo tenemos fácil, tan solo hay que ejecutar el siguiente comando:
git reset HEAD
El comando anterior eliminará el último commit del repositorio.
El problema viene cuando queremos borrar más de un commit (y no justamente el último). En estos casos tenemos dos opciones, utilizar «rebase» para borrar uno o más commit consecutivos o utilizar «cherry-pick«, que nos permitirá borrar commits no consecutivos.
git rebase
Siguiendo como referencia el «git log» anterior, queremos borrar los commits 2 y 3 (be54fcb y 22bb985). Como son consecutivos, podemos utilizar «rebase».
La utilización genérica de «rebase» sería la siguiente:
git rebase --onto <nombre de la branch>~<numero del primer commit a borrar> <nombre de la branch>
En el ejemplo en el que queremos borrar los commits 2 y 3:
git rebase --onto master~3 master~1 master
Como vemos, indicamos el primer commit desde el cual queremos borrar (el número 3) e indicamos hasta el primer commit que queremos mantener (el número 1), por lo que se borrarán los commits 3 y 2.
git Cherry-Pick
En este ejemplo, queremos borrar commits no consecutivos de nuestro repositorio. En concreto los commits número 2 y 4. Para este caso no nos queda más remedio que utilizar el comando «cherry-pick«.
Vamos primero con los pasos genéricos que deberemos seguir:
- Paso 1: Encontrar el commit justo anterior al commit que queremos borrar.
- Paso 2: Hacemos un «checkout» de ese commit con el comando:
git checkout
- Paso 3: Creamos una nueva rama utilizando nuestra posición actual:
git checkout -b
- Paso 4: Ahora tenemos que añadir el commit siguiente al commit que queremos borrado, para ello utilizamos el comando «cherry-pick»:
git cherry-pick
- Paso 5: Repetimos el paso 4 para todos los commits que queremos mantener.
- Paso 6: Volvemos a la branch original que queríamos arreglar:
git checkout
- Paso 7: Ahora hacemos un «hard reset» sobre la branch original al commit anterior al que queríamos borrar:
git reset --hard
- Paso 8: Hacemos un merge con la branch que hemos creado para borrar los commits:
git merge
- Paso 9: Hacemos un push al repositorio.
git push --force origin
Los veremos mucho más claro con un ejemplo. Con los siguientes comandos borraremos los commits 2 y 4 de nuestro repositorio:
# Checkout al commit justo anterior al que queremos borrar (en este ejemplo, al 5).
git checkout a3d37d5
# Creamos una nueva rama.
git checkout -b reparar
# Añadimos el commit contiguo al commit que queremos borrar (en este ejemplo, el 3).
git cherry-pick 22bb985
# Añadimos el commit contiguo al commit que queremos borrar (en este ejemplo, el 1).
git cherry-pick 8c2aafb
# Checkout master.
git checkout master
# Reset en la branch master al commit justo anterior al que queríamos borrar (en este ejemplo, al 5).
git reset --hard a3d37d5
# Hacemos merge de nuestra rama con la master.
git merge reparar
# Hacemos push de la rama master.
git push --hard origin master
Conclusión
Como nota final recordar que los comandos rebase y cherry-pick son muy peligrosos ⚠️ Solo deberíamos utilizarlos como última opción. Cuidado si borramos commits en ramas que están siendo utilizadas por otros usuarios, aunque lo más sensato es que cada rama sea de un desarrollador para que no haya conflictos y que en las ramas principales donde se mergea nunca se utilicen estas técnicas de borrado.
Artículo original de Jon Segador