2010-03-25 17 views
98

Necesito eliminar las ramas antiguas y no mantenidas de nuestro repositorio remoto. Estoy intentando encontrar una forma de enumerar las sucursales remotas en su última fecha de modificación, y no puedo.Enumerando cada rama y la fecha de su última revisión en git

¿Alguien sabe de una manera fácil de enumerar sucursales remotas de esta manera?

+1

duplicado posible de [¿Cómo puedo obtener una lista de las ramas git, ordenado por más reciente comprometerse?] (Http://stackoverflow.com/questions/5188320/how-can-i-get-a-list-of-git-branches-ordered-by-most-recent-commit) –

+2

Las respuestas a: http://stackoverflow.com/questions/5188320/ ¿cómo-puedo-obtener-una-lista-de-git-ramas-ordenadas-por-la más reciente-confirmación son todas mejores que las respuestas aquí –

Respuesta

133

commandlinefu tiene 2 proposiciones interesantes:

for k in `git branch | perl -pe s/^..//`; do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1`\\t$k; done | sort -r 

o:

for k in `git branch | sed s/^..//`; do echo -e `git log -1 --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k --`\\t"$k";done | sort 

es decir, para las secciones locales, en una sintaxis Unix. Usando git branch -r, puede mostrar de manera similar ramas remotas:

for k in `git branch -r | perl -pe 's/^..(.*?)(->.*)?$/\1/'`; do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1`\\t$k; done | sort -r 

Michael Forrest menciones in the comments que zsh requiere escapes para el sed expresión:

for k in git branch | perl -pe s\/\^\.\.\/\/; do echo -e git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1\\t$k; done | sort -r 

kontinuity añade in the comments:

Si usted quiere para agregarlo a su zshrc, se necesita el siguiente escape.

alias gbage='for k in `git branch -r | perl -pe '\''s/^..(.*?)(->.*)?$/\1/'\''`; do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1`\\t$k; done | sort -r' 

En varias líneas:

alias gbage='for k in `git branch -r | \ 
    perl -pe '\''s/^..(.*?)(->.*)?$/\1/'\''`; \ 
    do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | \ 
    head -n 1`\\t$k; done | sort -r' 
+1

gracias! ¡justo lo que necesitaba! –

+11

+1 por presentarme a commandlinefu! – hasen

+1

@hansen j: interesante, ¿no? Se lanzó unos meses después del lanzamiento público de Stack Overflow (http://codeinthehole.com/archives/16-Current-pet-project-Command-Line-Fu.html), y fue algo inspirada por SO. Vea también http://www.commandlinefu.com/commands/tagged/67/git para más git commandlinefu;) – VonC

17

Sólo para añadir a la observación del @VonC, tome su solución preferida y añadirla a su ~/.gitconfig lista de alias para mayor comodidad:

[alias] 
    branchdate = !git for-each-ref --sort='-authordate' --format='%(refname)%09%(authordate)' refs/heads | sed -e 's-refs/heads/--' 

A continuación, un simple "branchdate git" imprime la lista para usted ...

+3

+1 para mostrar cómo usarlo con .gitconfig! También cambié la cadena de formato a: '--format = '% (authordate)% 09% (objectname: short)% 09% (refname)'' que también obtiene el hash corto de cada rama. –

+0

Agradable. Añadiría "| tac" hasta el final para ordenarlo en orden inverso para que las ramas recién tocadas sean rápidamente visibles. – Ben

+0

No es necesario que '| tac', simplemente '--sort = 'authordate'' en lugar de' -authordate' –

67

Esto es lo que yo uso:

git for-each-ref --sort='-committerdate:iso8601' --format=' %(committerdate:iso8601)%09%(refname)' refs/heads 

Ésta es la salida:

2014-01-22 11:43:18 +0100  refs/heads/master 
2014-01-22 11:43:18 +0100  refs/heads/a 
2014-01-17 12:34:01 +0100  refs/heads/b 
2014-01-14 15:58:33 +0100  refs/heads/maint 
2013-12-11 14:20:06 +0100  refs/heads/d/e 
2013-12-09 12:48:04 +0100  refs/heads/f 

Por ramas remotas, justo utilizar "refs/mandos a distancia" en lugar de "refs/heads":

git for-each-ref --sort='-committerdate:iso8601' --format=' %(committerdate:iso8601)%09%(refname)' refs/remotes 

Es posible que desee llamar "git fetch --prune" antes de tener t la última información.

+4

Buen uso de for-each-ref y las opciones de formato. +1. Suena más fácil que los comandos a los que hago referencia en mi propia respuesta. – VonC

+1

retocando un poco: ------- git for-each-ref --sort = '- authordate: iso8601' --format = '% (authordate: relative)% 09% (refname: short)' refs/jefes ------- le da una fecha relativa y elimina los refs/heads – n8tr

+0

Para aquellos a los que no es inmediatamente obvio, creo que esto muestra información. estrictamente para las sucursales locales. – hBrent

13

edificio fuera de Olivier Croquette, me gusta usar una fecha relativa y acortando el nombre de la sucursal de esta manera:

git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads 

que le da salida:

21 minutes ago nathan/a_recent_branch 
6 hours ago  master 
27 hours ago nathan/some_other_branch 
29 hours ago branch_c 
6 days ago  branch_d 

Recomiendo hacer un archivo de fiesta para añadir todos tus alias favoritos y luego compartir el guión con tu equipo. He aquí un ejemplo para agregar simplemente ésta:

#!/bin/sh 

git config --global alias.branches "!echo ' ------------------------------------------------------------' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------'" 

a continuación, puedes hacer esto para obtener una lista rama local con un formato agradable y ordenado:

git branches 
+0

Buen formato ajustado. +1 – VonC

+0

Buena variación. +1 – ocroquette

1

hice dos variantes, basado en la respuesta de VonC.

Mi primera variante:

for k in `git branch -a | sed -e s/^..// -e 's/(detached from .*)/HEAD/'`; do echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset$k |%s" $k --`;done | sort | column -t -s "|" 

Este maneja locales & sucursales remotas (-a), se ocupa de Estado-cabeza separada (el comando ya sed, aunque la solución es una especie de crudo - que simplemente se cambia de información de rama separada con la palabra clave HEAD), agrega el asunto de confirmación (% s) y coloca las cosas en columnas a través de caracteres de tubería literales en la cadena de formato y pasando el resultado final al column -t -s "|". (Puede usar lo que sea como separador, siempre que sea algo que no espera en el resto de la salida).

Mi segunda variante es bastante hacky, pero realmente quería algo que todavía tenga un indicador de " esta es la rama en la que se encuentra actualmente "como lo hace el comando de rama.

CURRENT_BRANCH=0 
for k in `git branch -a | sed -e 's/\*/CURRENT_BRANCH_MARKER/' -e 's/(detached from .*)/HEAD/'` 
do 
    if [ "$k" == 'CURRENT_BRANCH_MARKER' ]; then 
     # Set flag, skip output 
     CURRENT_BRANCH=1 
    elif [ $CURRENT_BRANCH == 0 ]; then 
     echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset$k |%s" $k --` 
    else 
     echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset* %Cgreen$k%Creset |%s" $k --` 
     CURRENT_BRANCH=0 
    fi 
done | sort | column -t -s "|" 

Esto convierte el * que marca la rama actual en una palabra clave, y cuando el cuerpo del bucle ve la palabra clave en su lugar establece un indicador y salidas nada. El indicador se usa para indicar que se debe usar un formato alternativo para la siguiente línea. Como dije, totalmente hacky, ¡pero funciona! (En su mayoría. Por alguna razón mi última columna se está outdented en el ramal actual. Pero lo que realmente debería volver a hacer el trabajo real en lugar de ajustar esto más.)

+0

Desafortunadamente, la información en la respuesta VonCs no es una gran base para la creación de scripts. Vea aquí http://git-blame.blogspot.com/2013/06/checking-current-branch-programatically.html –

+0

Hmm. Eso muestra una forma de obtener el nombre de la rama actual, si tiene un nombre. ¿Hay alguna forma [preferida] de obtener una lista de sucursales que sea adecuada para las máquinas? (Y alguna forma de distinguir la rama actual, ya sea de esa salida directamente o de alguna manera preguntando git "¿es esta la misma referencia que HEAD?") – benkc

+0

'git for-each-ref' es la forma de script para procesar las ramas. Tendría que ejecutar el simbólico-ref una vez para obtener la rama actual. –

2

Ordenar remota ramas y la última fecha comprometerse para cada rama.

for branch in `git branch -r | grep -v HEAD`;do echo -e `git show --format="%ci %cr" $branch | head -n 1` \\t$branch; done | sort -r 
+1

Gracias por responder a la pregunta de OP con respecto al control remoto. – arcseldon

2

Esto es lo que me ocurrió después de revisar también this.

for REF in $(git for-each-ref --sort=-committerdate --format="%(objectname)" \ 
    refs/remotes refs/heads) 
do 
    if [ "$PREV_REF" != "$REF" ]; then 
     PREV_REF=$REF 
     git log -n1 $REF --date=short \ 
      --pretty=format:"%C(auto)%ad %h%d %s %C(yellow)[%an]%C(reset)" 
    fi 
done 

El cheque PREV_REF es eliminar duplicados si hay más de uno los puntos de ramificación a la misma se comprometen. (Como en la sucursal local que también existe en el control remoto.)

NOTA que según la solicitud OP, git branch --merged y git branch --no-merged son útiles para identificar qué ramas se pueden eliminar fácilmente. [https://git-scm.com/docs/git-branch]

0

Aquí hay una función que puede agregar a su perfil bash_ para facilitar esta tarea.

uso cuando se encuentra en un repositorio git:

  • branch impresiones de todas las ramas locales
  • branch -r impresiones de todas las ramas remotas

Función:

branch() { 
    local pattern="s/^..//" 
    local arg="" 
    if [[ [email protected] == "-r" ]]; then 
     pattern="s/^..(.*?)(->.*)?$/\1/" 
     arg=" -r " 
     echo '-r provided' 
    fi 
    for k in $(git branch $arg | perl -pe "$pattern"); do 
     echo -e $(git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1)\\t$k 
    done | sort -r 
} 
0

En Powershell, muestra ramas en el control remoto que ya están fusionados una d al menos dos semanas de edad. (Autor: relativa formato empieza a mostrar semanas en lugar de días a dos semanas)

$safeBranchRegex = "origin/(HEAD|master|develop)$"; 
$remoteMergedBranches = git branch --remote --merged | %{$_.trim()}; 
git for-each-ref --sort='authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/remotes | ?{$_ -match "(weeks|months|years) ago" -and $_ -notmatch "origin/(HEAD|master|qa/)"} | %{$_.substring($_.indexof("origin/"))} | ?{$_ -in $remoteMergedBranches} 
Cuestiones relacionadas