¿Alguna vez has visto este mensaje al intentar eliminar una rama?
$ git branch -d docs error: The branch 'docs' is not an ancestor of your current HEAD. If you are sure you want to delete it, run 'git branch -D docs'
Esto ocurre porque la rama que deseas eliminar no está incluída en la rama actual. Este es uno de esos casos en los que Git está intentando evitar que pierdas datos de forma accidental. Entonces, ¿cómo podemos determinar si una rama determinada (o un commit) forma parte de la rama actual, sin intentar eliminar dicha rama?
El comando git branch
provee algunas opciones que nos pueden ser de utilidad. La opción --contains
, por ejemplo, nos permite determinar si un commit específico fue integrado ya en la rama actual. Tal vez tienes el SHA de un commit que crees que ya aplicaste en la rama actual pero no estás seguro, o quieres chequear si aquél commit de tu proyecto open source favorito que reduce el uso de memoria en un 75% está incluído en la rama actual o no.
$ git log -1 tests commit d590f2ac0635ec0053c4a7377bd929943d475297 Author: Nick Quaranto <nick@quaran.to> Date: Wed Apr 1 20:38:59 2009 -0400 Green all around, finally. $ git branch --contains d590f2 tests * master
De acuerdo con los resultados obtenidos, podemos determinar que el commit d590f2
ha sido aplicado en las ramas tests
y master
.
Pero volvamos a nuestro problema original: ¿cómo determinar si una rama completa fue aplicada o no? Las opciones --merged
y --no-merged
hacen precisamente esto por nosotros. La primera nos dirá cuáles son las ramas que tienen aplicado el treeish especificado, mientras que la segunda opción hará exactamente lo contrario.
En este caso, la rama docs
no fue completamente aplicada en master
:
$ git branch --merged docs docs $ git branch --no-merged docs config * master tests $ git branch -d docs error: The branch 'docs' is not an ancestor of your current HEAD. If you are sure you want to delete it, run 'git branch -D docs'. $ git branch -D docs Deleted branch docs (884583c).
Si eres valiente, puedes usar una combinación de git rev-parse
y git rev-list
para determinar si un commit en particular está incluído en la historia de una rama o no. Originalmente yo lo hacía de ese modo hasta que alguien en el #git IRC channel me comentó la solución obvia utilizando git branch
. rev-parse
toma un treeish y lo convierte en el SHA al que pertenece. rev-list
permite listar commits de distintas maneras, suficientes como para merecer su propio artículo.
$ git rev-list master | grep $(git rev-parse docs) $ git rev-list master | grep $(git rev-parse tests) d590f2ac0635ec0053c4a7377bd929943d475297
El primer comando no devolvió nada, ya que el commit apuntado por HEAD
en docs
no existe en master
aún. Por otro lado, el commit apuntado por HEAD
en tests
es encontrado en master
y listado, tal como se esperaba.
Espero que este artículo te ahorre algo de tiempo cuando estés trabajando con múltiples ramas y necesites saber si ya fueron integradas o no. Si tienes alguna otra sugerencia acerca de cómo manejar esta situación, ¡dejanos un comentario!