¿Cuándo eliminar ramas en Git?

284

Supongamos que tenemos una aplicación estable.

Mañana, alguien informa de un gran error que decidimos corregir de inmediato. Así que creamos una rama para ese hotfix fuera de "master", lo llamamos "2011_Hotfix", y lo empujamos hacia arriba para que todos los desarrolladores puedan colaborar en solucionarlo.

Solucionamos el error y fusionamos "2011_Hotfix" en "maestro", así como en la rama de desarrollo actual. Y empuje "maestro".

¿Qué hacemos con "2011_Hotfix" ahora? ¿Debería permanecer allí como una rama para siempre hasta el final de los tiempos o deberíamos eliminarlo ahora, ya que ha cumplido su propósito? Parece impuro dejar ramas por todas partes, ya que la lista de ramas probablemente será muy larga, la mayoría de las cuales ya no son necesarias.

En caso de que deba eliminarse, ¿qué pasará con su historial? ¿Se mantendrá eso, aunque la rama real ya no esté disponible? Además, ¿cómo eliminaría una rama remota?

Anthony Compton
fuente
33
A menudo ayuda pensar en las ramas como ideas. Una regla general bastante buena es que si ha terminado de trabajar en las ideas que representa la rama, incluidas las pruebas realizadas y la incorporación de esos cambios (fusionándolos en el maestro), habrá terminado con la rama en sí.
Cascabel
3
Lo que me gustaría saber: si se elimina la revisión remota, ¿se eliminará localmente para todos los desarrolladores que colaboraron? Si no; ¿Cómo lograr esto? Creo que una persona migra la revisión al maestro, pero después de eso también debería limpiarse para todos los colaboradores, para evitar que agreguen confirmaciones a esa rama.
rolandow
1
No puede afectar los repositorios locales de las computadoras de sus compañeros de trabajo. Tienes que decirle que elimine la sucursal localmente o también puedes hacer cumplir este lado del servidor con git hooks / branch security para evitar los empujes de tu sucursal que deseas mantener eliminados
srz2

Respuestas:

183

Puede eliminar con seguridad una rama con git branch -d yourbranch. Si contiene cambios no fusionados (es decir, perderías confirmaciones al eliminar la rama), git te lo dirá y no lo eliminará.

Por lo tanto, eliminar una rama fusionada es barato y no te hará perder ningún historial.

Para eliminar una rama remota, use git push origin :mybranch, asumiendo que su nombre remoto es origen y que la rama remota que desea borrar se llama mybranch.

Artefacto2
fuente
35
"Eliminar una rama combinada es barato", pero también lo es mantenerlo. No hay un impacto significativo en el rendimiento en términos del tiempo o el espacio que usa git, si lo mantiene. Dicho esto, eliminaría la rama porque todas las confirmaciones ya están allí en la historia de master, por lo que hace las cosas mucho más limpias.
MatrixFrog
22
Una de mis razones para querer eliminar ramas es: Realizamos muchos cambios en las ramas (en realidad, todos los cambios) para que finalmente obtenga una larga lista cuando use el comando 'git branch'. Para el resumen, quiero acortar esa lista. Entonces las ramas viejas serán borradas. Los lanzamientos de Reale están etiquetados, por lo que no están en esta discusión para mí.
michel.iamit
77
Si bien estoy de acuerdo con eliminar ramas que ya se han fusionado, si desea ver una lista de ramas que no se han fusionado en su rama actual, puede usar: git branch --no-merged
lsklyut
51
@MatrixFrog Es barato mantenerse en términos de git, sin embargo, en el costo humano puede ser costoso. Acabo de ingresar a un proyecto con aproximadamente 40 sucursales, todas con nombres numéricos de sucursal. No tengo idea de qué es qué, y casi todas esas ramas están rancias. La sobrecarga de buscar a través de esas ramas y descubrir qué es lo que es agotador y lleva tiempo. Entonces sí, técnicamente es barato, pero en realidad no lo es. Me gusta mantener mi forma de repositorio de git. Si no está en desarrollo activo y se ha fusionado, elimínelo. Pero ese es solo mi MO y respeto que otros puedan hacer algo diferente.
dudewad
1
¿Cuál es el comando para hacer --no-mergedel predeterminado? Lo intenté git config --global --add branch.noMerged truey se agregó, pero no hizo ninguna diferencia.
Craig Silver
55

Lo que debe hacer es etiquetar todo lo que suelte. Mantenga ramas alrededor para cuando esté desarrollando activamente.

Eliminar ramas viejas con

git branch -d branch_name

Eliminarlos del servidor con

git push origin --delete branch_name

o la sintaxis anterior

git push origin :branch_name

que se lee como "no insertar nada en branch_name en origen".

Dicho esto, mientras el DAG (gráfico acíclico dirigido) pueda señalarlo, los commits estarán allí en la historia.

Google "git-flow" y eso puede dar más información sobre la gestión de lanzamiento, ramificación y etiquetado.

Adam Dymitruk
fuente
31

Dado que la pregunta tiene la etiqueta "github", también agregaría esto: específicamente en Github , si solicita una rama y se fusiona (ya sea a través de la interfaz de usuario o fusionando la rama de la solicitud de extracción), no lo hará perderá los datos de la solicitud de extracción (incluidos los comentarios), incluso si elimina la rama .

Una consecuencia de esto: si incorpora solicitudes de extracción como parte de su flujo de trabajo (que combina muy bien con las revisiones de código), puede eliminar ramas de forma segura tan pronto como se fusionen. Esto es tan común que recientemente Github agregó una característica (dulce) que muestra un botón de "eliminar rama" justo después de combinar una solicitud de extracción.

Pero vale la pena notar que cada grupo debe adoptar el flujo de trabajo que más le convenga (y puede llevar o no a eliminar tales ramas). Mi equipo de trabajo actual, por ejemplo, poda todas las ramas que no están relacionadas con el maestro o la implementación (por ejemplo, producción, puesta en escena, etc.) tan pronto como se fusionan sus solicitudes de extracción, y todavía tenemos un seguimiento completo de cómo se formaron los compromisos relacionados cada mejora incremental de cada producto.

Por supuesto, ninguna gestión del historial (solicitudes de extracción o de otro tipo) reemplaza el etiquetado adecuado de las versiones (que preferiblemente automatiza con la misma herramienta / script que implementa / empaqueta una versión), por lo que siempre puede cambiar rápidamente a lo que sea que estén sus usuarios. en un momento dado El etiquetado también es la clave para resolver su problema original: si establece que cualquier rama fusionada con las ramas "de trabajo" puede y debe ser eliminada, y que cualquiera que esté fusionado con una etiqueta de versión, "producción", etc., no debe , siempre tendrá las revisiones activas hasta que se integren en una versión futura.

chesterbr
fuente
2
Gracias por explicar por qué Github me estaba mostrando un botón "Eliminar rama".
Todd Owen
Estamos usando sourcetree y ofrece la opción de mantener abiertas la rama de revisión local y la rama de revisión remota. Pensé que cerrar una rama de revisión significaba eliminarla y no se puede volver a usar. Por ejemplo, necesitamos impulsar las soluciones rápidas todos los días durante los próximos 5 días. Luego lo cerramos. Pero digamos que el sexto día, necesitamos otra revisión. ¿Creamos una nueva rama de revisión?
Danger14
Es lo que la gente suele hacer. Si nombrarlos individualmente no es factible, puede nombrarlos según el día o la referencia del sistema de tickets que los administra (si corresponde). Por supuesto, se supone que los flujos de trabajo de git se deben aplicar sobre la base de "lo que funcione mejor para su equipo", así que no se preocupe si decide trabajar de manera diferente.
chesterbr
7

Agregaría que la desventaja de eliminar ramas es que romperá cualquier hipervínculo a esas ramas en GitHub (esta pregunta está etiquetada como github). Obtendrá un 404 Not Founderror para esos enlaces. Es por eso que cambio mis enlaces para que apunten a una confirmación o etiqueta después de eliminar una rama en GitHub.

Debido a que algunos enlaces no se pueden cambiar, como en el correo electrónico, ahora evito los hipervínculos a las ramas de GitHub por completo y los enlaces a una confirmación o etiqueta desde el primer día.

Prefiero eliminar ramas después de que se fusionen. Esto evita el desorden visual de una larga lista de ramas en su repositorio. Estas ramas también se propagan a todos los tenedores del repositorio.

Primero borro mi sucursal local. Esto evita que sea empujado accidentalmente más tarde.

git branch -d branchName

Luego elimino la rama de seguimiento remoto

git branch -dr remoteName\branchName

Luego borro la rama en GitHub. Yo uso la interfaz web, pero el comando equivalente está debajo.

git push remoteName :branchName

Incluso si la rama nunca se fusiona, normalmente me gustaría mantener los compromisos para la posteridad. Sin embargo, todavía me gusta eliminar la rama. Para distribuir los commits y evitar que el recolector de basura los coma, hago una etiqueta anotada que apunta al mismo commit que la rama eliminada.

git tag -a tagName commitOrBranchName

Luego empujo la etiqueta a github

git push remoteName tagName
Mark F Guerra
fuente
¿Cuándo se come el recolector de basura las confirmaciones de la rama? ¿Necesita etiquetar y empujar la etiqueta antes de eliminar la rama?
Jared Thirsk
4

Parece que desea eliminar la 2011_Hotfixrama sin perder su historial. Discutiré la eliminación primero y la historia después.

Los gitmétodos habituales de eliminación de ramas ya se han descrito anteriormente y funcionan como se esperaba. gitno tiene un comando de una o dos palabras que significa "Oye git, elimina tanto la rama local como la remota". Pero este comportamiento se puede imitar a través del script de shell. Por ejemplo, tome el script de shell de Zach Holman 'git-nuke' . Es muy simple:

#!/bin/sh
git branch -D $1
git push origin :$1

Ponga esto en un archivo ejecutable (por ejemplo, git-nuke) en uno de sus $PATHdirectorios. Si no está en la 2011_Hotfixrama, simplemente ejecutando git-nuke 2011_Hotfixeliminará las ramas locales y remotas. Esto es mucho más rápido y sencillo, aunque quizás más peligroso, que los gitcomandos estándar .

Su preocupación por preservar la historia es buena. En este caso, no debes preocuparte. Una vez que se fusionan 2011_Hotfixen mastertodos los commits de 2011_Hotfixse añadirán a master's se comprometen historia. En resumen, no perderá el historial de una simple fusión.

Tengo una palabra más para agregar que tal vez esté más allá del alcance de su pregunta, pero de todos modos es relevante. Imaginemos que hay 20 pequeños compromisos de "trabajo en progreso" 2011_Hotfix; sin embargo, solo desea 2011_Hotfixque se agregue una confirmación completa al masterhistorial de. ¿Cómo se combinan las 20 pequeñas confirmaciones en una gran confirmación? Afortunadamente, le gitpermite consolidar múltiples confirmaciones en una confirmación mediante el uso git-rebase. No explicaré aquí cómo funciona eso; sin embargo, si está interesado, la documentacióngit-rebase es excelente. Tenga en cuenta que git rebasereescribe el historial, por lo que debe usarse con prudencia, especialmente si es nuevo en él. Finalmente, su 2011_Hotfixescenario es sobre un equipo de desarrollo, no un desarrollo en solitario. Si los miembros del equipo del proyecto usangit rebase, es aconsejable que el equipo tenga pautas explícitas sobre el uso git rebasepara que algún desarrollador de vaqueros en el equipo no dañe involuntariamente la githistoria de un proyecto .

jfmercer
fuente
3

Si se fusionó con éxito nuevamente y tal vez incluso se etiquetó, diría que ya no tiene uso. Para que pueda hacerlo con seguridad git branch -d branchname.

Michael Fürstenberg
fuente
2

Si desea podar ramas locales que se han eliminado del origen, también puede podar, mientras usa git fetch

git fetch --prune
huch
fuente
0

Puede eliminar ramas en todas las principales interfaces de usuario web, como github, BitBucket. Después de eliminar la sucursal en línea, puede eliminar la sucursal local usando

git remote prune origin
tkruse
fuente