¿Por qué puedo pagar una rama que se eliminó en GitHub?

26

En nuestro repositorio GitHub, un compañero de trabajo sacó una rama llamada release. Pero cuando ejecuto git checkout releaselocalmente, siempre obtengo la rama eliminada release. Igual, incluso cuando revisé otra rama, eliminé la releaserama con git branch -D releasey corrí nuevamente git checkout release.

¿Hay algo que arreglar en el repositorio de GitHub, o debo arreglar algo localmente?

Tim
fuente
1
¿Qué da git branch --remotesalida, después de correr git fetch? Es posible que deba podar git fetch -ppara olvidar las ramas remotas eliminadas.
Stephen Kitt
2
Si esa rama alguna vez fue empujada a GitHub, y usted retiró después de eso, entonces también tiene una copia de la rama. Cada repositorio git está completo en sí mismo, a menos que haya usado un clon superficial o algo así.
muru
@StephenKitt: Gracias. git branch --remotesalida origin/release. ¿Quiere ejecutar git fetch -psin argumentos adicionales y eliminará todas las ramas remotas eliminadas?
Tim
1
Sí, git fetch -psin argumentos adicionales se podarán todas las ramas remotas eliminadas.
Stephen Kitt
1
¡Bienvenido al mundo del control de versiones distribuidas!
chrylis -on strike-

Respuestas:

24

Después de eliminar una rama en el lado remoto, aún puede ver esta rama remota anteriormente recuperada localmente, vea:

$ git branch -a
[...]
release
remotes/origin/release
[...]

Solo eliminó el "lanzamiento" pero no el "control remoto / origen / lanzamiento". Eliminarlo así:

$ git branch -rd origin/release

O elimine todas las ramas recuperadas que ya no existen en el lado remoto:

$ git remote prune origin 
rudimeier
fuente
Gracias. En git branch -rd origin/release, ¿qué -rsignifica? ¿ -dSignifica lo mismo que -D? Se git branch -rd origin/releasepuede reemplazar con git branch -d remotes/origin/release?
Tim
@Tim: del manual; -r: List or delete (if used with -d) the remote-tracking branches.; -D:Shortcut for --delete --force.
looper
Gracias. Se git branch -rd origin/releasepuede reemplazar con git branch -d remotes/origin/release?
Tim
@Tim no se -rrefiere a ramas remotas , es necesario. Las ramas locales y remotas se almacenan en diferentes directorios, comparar ls -l .git/refs/headsy ls -l .git/refs/remotes. También podría tener una rama local llamada remotes/origin/releaseque se eliminaría sin -r. Esto puede sonar confuso, pero puedes jugar, crear ramas con nombres extraños y ver cómo se ve .git/.
rudimeier
15

Cuando las ramas se eliminan de forma remota, debe podar su repositorio local; la forma más fácil de hacerlo es con

git fetch -p

Esto actualizará su repositorio local con todos los cambios realizados en el repositorio remoto, pero sin actualizar ninguna de sus sucursales locales. Después de ejecutar esto,

git branch --remote

ya no mostrará la rama remota eliminada.

Los repositorios de git están completos, ya sea en su propio sistema o en el servidor. Entonces, cuando clonas por primera vez un repositorio, obtienes una copia completa, y tu git local "sabe" acerca de todas las ramas remotas, así como tus ramas locales. Esta información no se sincroniza automáticamente, por lo que cuando su colega eliminó la releaserama en el servidor, su repositorio git local no perdió su noción de una releaserama remota . La sincronización con las git fetchactualizaciones de toda la información local en las sucursales remotas para que coincidan con el estado del servidor (estrictamente hablando, repositorio remoto, donde sea que esté), pero sin eliminar ninguna información local en las sucursales remotas. La poda con git fetch -p(o git fetch --prune, o git remote prune) elimina la información local en ramas remotas que se han eliminado.

Stephen Kitt
fuente
Gracias. "actualice su repositorio local con todos los cambios realizados en el repositorio remoto, pero sin actualizar ninguna de sus sucursales locales". ¿Qué actualización es esa, dado que no es una actualización de mis sucursales locales?
Tim
Son todas las actualizaciones remotas. Su repositorio git local distingue sus ramas locales y las ramas remotas, pero las ramas remotas no están mágicamente sincronizadas con el servidor, sino que también existen localmente (como almacenadas en su repositorio git local). La obtención sincroniza su repositorio local con el repositorio remoto y actualiza el estado de las ramas remotas; de forma predeterminada, las ramas remotas eliminadas no se eliminan de la información local en las ramas remotas, -p( --prune) obliga a eso.
Stephen Kitt
Gracias. ¿Por qué no la supresión de la releaserama de git branch -D releaseantes de git checkout releasehacer git checkout releasedejar de recibir la releaserama?
Tim
1
Porque git checkout releasevolverá a crear automáticamente una rama si hay una rama remota con ese nombre.
Stephen Kitt
Por "rama remota", ¿se refiere a una rama en mi repositorio local o en el repositorio de Github? Si es anterior, git branch -D releaseya ha eliminado la releaserama en mi repositorio local; Si es esto último, un compañero de trabajo ha eliminado la releaserama en GitHub; Así que todavía no estoy seguro de por qué "volverá a crear automáticamente una rama si hay una rama remota con ese nombre".
Tim
3

Tim: Git se distribuye VCS, por lo que cuando clonas un repositorio de remoto a tu local, clona todo (historial). Entonces, cuando clonaste tu repositorio, tenía una rama llamada lanzamiento. Desde que su colega eliminó la rama de lanzamiento de forma remota, hasta que haga una poda git fetch -po elimine esa rama explícitamente, su local tendrá esa rama.

ManiVI
fuente
3
¿Cómo difiere esta respuesta de las respuestas ya presentes?
Stephen Rauch
1

Quizás un poco tangencial, pero la perspectiva de este sitio podría ayudar a comprender el tema general de la eliminación de ramas:

http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/

Hay una superposición con algunos de los temas que ya se han discutido aquí, pero el enfoque está en la limpieza: eliminar sucursales, remotas y locales, que ya no son necesarias en un entorno colaborativo. En particular, el git branch --mergedcomando identifica ramas que son seguras para eliminar debido a la fusión con su línea principal (o cualquier rama que le interese). Si está colaborando, algunos mini guiones más elegantes como este presentarán las cosas en un formato agradable y digerible con fechas y autores.

for branch in `comm -12  <(git branch --merged|awk '{print($1)}') <(git branch -r --merged|awk '{print($1)}'|awk -F \/ '{print($2)}')`; do echo -e `git show --format="%ci %cr %an" $branch | head -n 1` \\t$branch; done | sort -r

(Lamentablemente, "agradable, digerible" no se aplica al formato de los propios scripts).

Capa B
fuente