¿Cuáles son las diferencias entre git remote prune, git prune, git fetch – run, etc.

Mi situación es esta … alguien que trabaja en el mismo repository ha eliminado una sucursal de su repository local y remoto …

La mayoría de las personas que han preguntado acerca de este tipo de problema en Stack Overflow u otros sitios tienen el problema de que las ramificaciones aún se muestran en su twig de seguimiento remoto git branch -a en la parte inferior:

 * master develop feature_blah remotes/origin/master remotes/origin/develop remotes/origin/feature_blah remotes/origin/random_branch_I_want_deleted 

Sin embargo, en MI situación la twig que no debería estar allí, es local:

 * master develop feature_blah random_branch_I_want_deleted remotes/origin/master remotes/origin/develop remotes/origin/feature_blah 

Cuando hago algo de lo siguiente, no se elimina localmente:

 $ git prune 

También probé:

 $ git remote prune origin $ git fetch --prune 

Información más útil: cuando compruebo git remote show origin así es como se ve:

 * remote origin Fetch URL: utilities:homeconnections_ui.git Push URL: utilities:homeconnections_ui.git HEAD branch: master Remote branches: master tracked develop tracked feature_blah tracked other123 tracked other444 tracked other999 tracked Local branches configunetworking for 'git pull': develop merges with remote develop feature_blah merges with remote other999 master merges with remote master random_branch_I_want_deleted merges with remote random_branch_I_want_deleted Local refs configunetworking for 'git push': develop pushes to develop (local out of date) master pushes to master (up to date) feature_blah pushes to feature_blah(up to date) 

Tenga en count que solo está en la sección titulada Local branches configunetworking for 'git pull':

¿Por qué?

No te culpo por frustrarte con esto. La mejor manera de ver esto es esto. Hay potencialmente tres versiones de cada twig remota:

  1. La twig real en el repository remoto
  2. Su instantánea de esa twig localmente (almacenada en refs/remotes/... )
  3. Y una sucursal local que podría estar rastreando la twig remota

Comencemos con git prune . Esto elimina objects que ya no se referencen, no references. En tu caso, tienes una sucursal local. Eso significa que hay una reference llamada random_branch_I_want_deleted que se refiere a algunos objects que representan el historial de esa twig. Entonces, por definición, git prune random_branch_I_want_deleted no eliminará random_branch_I_want_deleted . Realmente es una manera de eliminar datos que se han acumulado en Git pero no está siendo referenceda por nada útil. En general, no afecta su vista de ninguna twig.

git remote prune origin y git fetch --prune ambos operan bajo references en refs/remotes/... (Me referiré a estos como references remotas). No afecta a las sucursales locales. La versión git remote es útil si solo quiere eliminar references remotas bajo un control remoto particular. De lo contrario, los dos hacen exactamente lo mismo. Entonces, en resumen, git remote prune git fetch --prune y git fetch --prune operan en el número 2 anterior.

Para eliminar una sucursal local, debe usar git branch -d (o -D si no está fusionada en ninguna parte). FWIW, no existe el command git para eliminar automáticamente las twigs locales de seguimiento si una twig remota desaparece.

git remote prune git fetch --prune y git fetch --prune hacen lo mismo: eliminar los refs en las twigs que no existen en el control remoto, como dijiste. El segundo command se conecta al control remoto y recupera sus twigs actuales antes de la poda.

Sin embargo, no toca las twigs locales que ha revisado, que puede simplemente eliminar con

 git branch -d random_branch_I_want_deleted 

Reemplazar -d por -D si la twig no se fusiona en otra parte

git prune hace algo diferente, purga objects inalcanzables, aquellos commits que no son alcanzables en ninguna twig o label, y por lo tanto ya no son necesarios.

Tenga en count que una diferencia entre git remote --prune y git fetch --prune está siendo corregida, con commit 10a6cc8 , por Tom Miller ( tmiller ) (para git 1.9 / 2.0, Q1 2014):

Cuando tenemos una twig de seguimiento remoto llamada " frotz/nitfol " de una búsqueda anterior, y la frotz/nitfol ascendente ahora tiene una twig llamada "** frotz " **, la fetch no puede eliminar " frotz/nitfol " con un " git fetch --prune "from the upstream.
git informaría al usuario que use " git remote prune " para solucionar el problema.

Entonces: cuando un repository en sentido ascendente tiene una bifurcación ("frotz") con el mismo nombre que una jerarquía de sucursal ("frotz / xxx", una posible convención de nomenclatura de sucursal ), git remote --prune estaba teniendo éxito (al limpiar el seguimiento remoto twig de su repository), pero git fetch --prune estaba fallando.

Ya no:

Cambia la forma en que funciona " fetch --prune " moviendo la operación de poda antes de la operación de captación.
De esta manera, en lugar de advertir al usuario de un conflicto, lo soluciona automáticamente.

En caso de que alguien esté interesado. Aquí hay un script de shell rápido que eliminará todas las sucursales locales que no se rastrean de forma remota. Una advertencia: esto eliminará cualquier twig que no se rastree remotamente, independientemente de si se fusionó o no.

Si ustedes ven algún problema con esto, háganmelo saber y lo arreglaré (etc., etc.)

Guárdelo en un file llamado git-rm-ntb ( git-rm-ntb como sea) en PATH y ejecute:

git-rm-ntb <remote1:optional> <remote2:optional> ...

 clean() { REMOTES="$@"; if [ -z "$REMOTES" ]; then REMOTES=$(git remote); fi REMOTES=$(echo "$REMOTES" | xargs -n1 echo) RBRANCHES=() while read REMOTE; do CURRBRANCHES=($(git ls-remote $REMOTE | awk '{print $2}' | grep 'refs/heads/' | sed 's:refs/heads/::')) RBRANCHES=("${CURRBRANCHES[@]}" "${RBRANCHES[@]}") done < <(echo "$REMOTES" ) [[ $RBRANCHES ]] || exit LBRANCHES=($(git branch | sed 's:\*::' | awk '{print $1}')) for i in "${LBRANCHES[@]}"; do skip= for j in "${RBRANCHES[@]}"; do [[ $i == $j ]] && { skip=1; echo -e "\033[32m Keeping $i \033[0m"; break; } done [[ -n $skip ]] || { echo -e "\033[31m $(git branch -D $i) \033[0m"; } done } clean $@ 

Esto es un poco brutal, pero si no te importa la historia local y todas las twigs importantes ya están comprometidas. Este es un reinicio rápido:

 rm -rf .git git init git remote add origingit@github.com:my/test.git git checkout master -f