2010-04-10 6 views
130

Viniendo de svn, comenzando a familiarizarse con git.¿La eliminación de una rama en git la elimina del historial?

Cuando se elimina una rama en git, ¿se elimina del historial?

En svn, puede recuperar fácilmente una bifurcación revocando la operación de eliminación (fusión inversa). Como todas las eliminaciones en svn, la rama nunca se borra realmente, simplemente se elimina del árbol actual.

Si la rama se borra realmente del historial en git, ¿qué ocurre con los cambios que se fusionaron de esa rama? ¿Están retenidos?

Respuesta

176

Las ramas son solo indicadores para cometer en git. En git cada commit tiene un árbol fuente completo, es una estructura muy diferente de svn donde todas las ramas y etiquetas (por convención) viven en 'carpetas' separadas del repositorio junto con el 'trunk' especial.

Si la rama se fusionó en otra rama antes de ser eliminada, todas las confirmaciones seguirán siendo accesibles desde la otra rama cuando se elimine la primera. Ellos permanecen exactamente como estaban.

Si la bifurcación se elimina sin fusionarse con otra bifurcación, las confirmaciones en esa bifurcación (hasta el punto en el bifurcado de una confirmación que todavía se puede alcanzar) dejarán de estar visibles.

Las confirmaciones se mantendrán en el repositorio y es posible recuperarlas inmediatamente después de la eliminación, pero finalmente serán recogidas.

+2

Gracias por la respuesta. ¿Podría aclarar a qué se refiere con "cada compromiso tiene un árbol fuente completo"? Según lo entiendo, cada commit en git es un conjunto de deltas que se refieren a una confirmación principal, no a un árbol completo. –

+0

No, cada commit es el estado del árbol en un punto dado. Los deltas solo se calculan más tarde para mostrar y rebasar y todo lo demás, pero el ID de confirmación es el hash de todo el árbol. – ben

+1

@Ken Liu: una confirmación contiene punteros a cero o más confirmaciones principales, un objeto de árbol y algunos metadatos sobre la confirmación. El compromiso, por lo tanto, identifica de manera única tanto un árbol de fuentes de par como, cuando se lo compara con sus padres, los cambios que introdujo. –

62

En Git, las ramas son solo punteros (referencias) para confirmaciones en un gráfico acíclico dirigido (DAG) de confirmaciones. Esto significa que al eliminar una rama se eliminan solo las referencias a las confirmaciones, lo que puede hacer que algunas confirmaciones en el DAG sean inalcanzables y, por lo tanto, invisibles. Pero todas las confirmaciones que estaban en una bifurcación eliminada seguirían estando en el repositorio, al menos hasta que se eliminen las confirmaciones inalcanzables (por ejemplo, usando git gc).

Tenga en cuenta que git branch -d se rehusaría a eliminar una rama si no puede estar seguro de que eliminarla no dejaría commits inalcanzables. Necesita usar el git branch -D más fuerte para forzar el borrado de una bifurcación si puede dejar commits inalcanzables.

Tenga en cuenta también que las confirmaciones inalcanzables, si están presentes, son solo aquellas confirmaciones entre el último consejo de una sucursal eliminada y una confirmación que se fusionó con otra sucursal existente, cualquier confirmación etiquetada o el punto de bifurcación; lo que sea más tarde. Por ejemplo, en la siguiente situación:

 
----O----*----*----/M----* <-- master <-- HEAD 
    \   /
     \--.----.--/--x---y  <-- deleted branch 

sólo se compromete 'x' e 'y' se convirtió en inalcanzable después de borrar la rama.

Si opere en un circuito eliminado dentro del período gc.reflogExpire, por defecto 90 días, usted tendría la última punta de una rama eliminada registrada en reflog cabeza (ver git reflog show HEAD, o git log --oneline --walk-reflogs HEAD). Debería poder usar el refrito HEAD para recuperar el puntero eliminado. Tenga en cuenta también que, en este caso, las confirmaciones inalcanzables en una rama eliminada quedarían protegidas de la eliminación (eliminación) dentro del período gc.reflogExpireUnreachable, que de forma predeterminada es de 30 días.

Si no puede encontrar la punta de una rama acaba de eliminar en reflog para la cabeza, se puede tratar de utilizar git fsck encontrar "inalcanzable cometer <sha1>", y examinar los (a través de git show <sha1> o git log <sha1>) para encontrar la punta de la rama eliminada.

Independiente de cómo se encuentre la punta de una rama borrado, puede deshacer la eliminación, o más bien volver a crear una rama acaba de eliminar el uso de

git branch <deleted-branch> <found-sha1-id> 

Nota sin embargo, que reflog de una rama se perdería.


También hay git-resurrect.sh guión en contrib/ que ayuda a encontrar rastros de una punta de la rama con el nombre dado y resucitar (recuperar) de ella.

+0

¡Impresionante! 'git reflog show HEAD' enumeró el commit y creé una nueva rama como dijiste, perfecta. –

1

Si le preocupan las ramas borradas accidentalmente y no tiene una copia local de su repositorio, existen extensiones para los servidores Git empresariales como Gerrit que detectarán reescrituras de historial y borrados de sucursales, los respaldarán en un archivo especial ref para que se puedan restaurar si es necesario y no se podará con la recolección de basura. Los administradores de Gerrit aún pueden eliminar confirmaciones seleccionadas si es necesario por razones legales.

Cuestiones relacionadas