¿Cómo puedo get una list de las twigs de git orderadas por la confirmación más reciente?

Quiero get una list de todas las sucursales en un repository Git con las twigs más "frescas" en la parte superior, donde la twig "más reciente" es la que se ha comprometido más recientemente (y, por lo tanto, es más probable que sea una Quiero prestarle atención)

¿Hay alguna forma de que pueda usar Git para (a) orderar la list de twigs por la confirmación más reciente, o (b) get una list de twigs junto con la date de último compromiso de cada una, en algún tipo de formatting legible por máquina?

En el peor de los casos, siempre podría ejecutar git branch para get una list de todas las twigs, analizar su salida y luego git log -n 1 branchname --format=format:%ci para cada una, para get la date de confirmación de cada twig. Pero esto se ejecutará en una caja de Windows, donde girar un nuevo process es relativamente costoso, por lo que el lanzamiento del ejecutable de git una vez por twig podría ser lento si hay muchas twigs. ¿Hay alguna manera de hacer todo esto con un solo command?

Utilice la opción --sort=-committerdate de git for-each-ref ;
También disponible desde Git 2.7.0 para la git branch :

Uso Básico:

 git for-each-ref --sort=-committerdate refs/heads/ # or using git branch (since version 2.7.0) git branch --sort=-committerdate # DESC git branch --sort=committerdate # ASC 

Resultado:

resultado

Uso avanzado:

 git for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:networking)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))' 

Resultado:

resultado

Para ampliar la respuesta de Jakub y la sugerencia de Joe, lo siguiente eliminará los "refs / heads /", por lo que la salida solo muestra los nombres de las twigs:

 git for-each-ref --count=30 --sort=-committerdate refs/heads/ --format='%(refname:short)' 

¡Probado!

Aquí está el código óptimo, que combina las otras dos respuestas:

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

Aquí hay un command simple que enumera todas las twigs con los últimos commits:

 git branch -v 

Para orderar por la confirmación más reciente, use

 git branch -v --sort=committerdate 

Fuente: http://git-scm.com/book/es/Git-Branching-Branch-Management

También necesitaba colors, tags y references remotas sin ningún duplicado:

 for ref in $(git for-each-ref --sort=-committerdate --format="%(refname)" refs/heads/ refs/remotes ); do git log -n1 $ref --pretty=format:"%Cgreen%cr%Creset %C(yellow)%d%Creset %C(bold blue)<%an>%Creset%n" | cat ; done | awk '! a[$0]++' 

Debido a que las citas pueden ser difíciles, aquí el alias de bash:

 alias glist='for ref in $(git for-each-ref --sort=-committerdate --format="%(refname)" refs/heads/ refs/remotes ); do git log -n1 $ref --pretty=format:"%Cgreen%cr%Creset %C(yellow)%d%Creset %C(bold blue)<%an>%Creset%n" | cat ; done | awk '"'! a["'$0'"]++'" 

Yo uso el siguiente alias:

recent = "!r(){git for-each-ref --sort=-committerdate refs/heads --format='%(HEAD)%(color:yellow)%(refname:short)|%(color:bold green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)'|column -ts'|'}; r"

que produce: resultado

Editar: use '|' para separar, gracias a @ Björn Lindqvist

Actualización: agregado * antes de la twig actual, gracias a @elhadi
Editar: se corrigió un caso en el que la twig actual era una subcadena de otra twig

Editar: use una syntax más simple para la twig actual, gracias a @Joshua Skrzypek

Las otras respuestas no parecen permitir pasar -vv para get una salida detallada.

Así que aquí hay una línea que ordera git branch -vv por date de compromiso, preservando el color, etc.

 git branch -vv --color=always | while read; do echo -e $(git log -1 --format=%ct $(echo "_$REPLY" | awk '{print $2}' | perl -pe 's/\e\[?.*?[\@-~]//g') 2> /dev/null || git log -1 --format=%ct)"\t$REPLY"; done | sort -r | cut -f 2 

Si además desea imprimir la date de compromiso, puede usar esta versión en su lugar:

 git branch -vv --color=always | while read; do echo -e $(git log -1 --format=%ci $(echo "_$REPLY" | awk '{print $2}' | perl -pe 's/\e\[?.*?[\@-~]//g') 2> /dev/null || git log -1 --format=%ci)" $REPLY"; done | sort -r | cut -d ' ' -f -1,4- 

Muestra de salida:

 2013-09-15 master da39a3e [origin/master: behind 7] Some patch 2013-09-11 * (detached from 3eba4b8) 3eba4b8 Some other patch 2013-09-09 my-feature e5e6b4b [master: ahead 2, behind 25] WIP 

Probablemente sea más fácil de dividir en varias líneas:

 git branch -vv --color=always | while read; do # The underscore is because the active branch is preceded by a '*', and # for awk I need the columns to line up. The perl call is to strip out # ansi colors; if you don't pass --color=always above you can skip this local branch=$(echo "_$REPLY" | awk '{print $2}' | perl -pe 's/\e\[?.*?[\@-~]//g') # git log fails when you pass a detached head as a branch name. # Hide the error and get the date of the current head. local branch_modified=$(git log -1 --format=%ci "$branch" 2> /dev/null || git log -1 --format=%ci) echo -e "$branch_modified $REPLY" # cut strips the time and timezone columns, leaving only the date done | sort -r | cut -d ' ' -f -1,4- 

Esto también debería funcionar con otros arguments para git branch , por ej. -vvr para enumerar twigs de rastreo remoto, o -vva para listr tanto el rastreo remoto como las sucursales locales.

git 2.7 (Q4 2015) introducirá la sorting de twigs usando directamente la git branch :
Consulte commit aa3bc55 , commit aedcb7d , commit 1511b22 , commit f65f139 , … (23 de septiembre de 2015), commit aedcb7d , commit 1511b22 , commit ca41799 (24 de septiembre de 2015) y commit f65f139 , … (23 de septiembre de 2015) por Karthik Nayak ( KarthikNayak ) .
(Fusionada por Junio ​​C Hamano – gitster – in commit 7f11b48 , 15 de octubre de 2015)

En particular, cometa aedcb7d :

branch.c : use las API ' ref-filter '

Haga que ' branch.c ' use las API ' ref-filter ' para iterar a través de la sorting de refs. Esto elimina la mayor parte del código utilizado en ' branch.c ' reemplazándolo con llamadas a la biblioteca ' ref-filter '.

Agrega la opción --sort=<key> :

Ordenar según la key dada.
Prefijo - para clasificar en order descendente del valor.

Puede usar la --sort=<key> varias veces, en cuyo caso la última key se convierte en la key principal.

Las keys compatibles son las mismas que en git for-each-ref .
La order de sorting pnetworkingeterminada se ordera según el refname completo (incluido el prefijo refs refs/... ). Esto enumera el HEAD separado (si está presente) primero, luego las twigs locales y finalmente las twigs de seguimiento remoto.

Aquí:

 git branch --sort=-committerdate 

Ver también commit 9e46833 (30 Oct 2015) por Karthik Nayak ( KarthikNayak ) .
Ayudado por: Junio ​​C Hamano ( gitster ) .
(Combinado por Junio ​​C Hamano – gitster – en la confirmación 415095f , 03 nov 2015)

Al orderar según valores numéricos (por ejemplo, --sort=objectsize ) no hay comparación de retroceso cuando ambos refs tienen el mismo valor. Esto puede causar resultados inesperados (es decir, el order de listr references con valores iguales no puede ser pnetworkingeterminado) como lo señala Johannes Sixt ( $ gmane / 280117 ).

Por lo tanto, se recurre a la comparación alfabética basada en la reference cuando el otro criterio es igual .

 $ git branch --sort=objectsize * (HEAD detached from fromtag) branch-two branch-one master 

Me gusta usar una date relativa y acortar el nombre de la twig de esta manera:

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

Lo que te 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 file bash para agregar todos sus alias favoritos y luego compartir el guión con su equipo. Aquí hay un ejemplo para agregar solo este:

 #!/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, puede hacer esto para get una list de sucursales locales bien formateada y orderada:

 git branches 

Actualización: haga esto si quiere colorear:

 #!/bin/sh # (echo ' ------------------------------------------------------------‌​' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------‌​') | grep --color -E "$(git rev-parse --abbrev-ref HEAD)$|$" 

Agrega un poco de color (ya que pretty-format no está disponible)

 [alias] branchdate = for-each-ref --sort=-committerdate refs/heads/ --format="%(authordate:short)%09%(objectname:short)%09%1B[0;33m%(refname:short)%1B[m%09" 

Tuve el mismo problema, así que escribí una gem Ruby llamada Twig . Enumera las twigs en order cronológico (lo más nuevo primero) y también le permite establecer una edad máxima para que no se enumeren todas las twigs (si tiene muchas). Por ejemplo:

 $ twig issue status todo branch ----- ------ ---- ------ 2013-01-26 18:00:21 (7m ago) 486 In progress Rebase optimize-all-the-things 2013-01-26 16:49:21 (2h ago) 268 In progress - whitespace-all-the-things 2013-01-23 18:35:21 (3d ago) 159 Shipped Test in prod * refactor-all-the-things 2013-01-22 17:12:09 (4d ago) - - - development 2013-01-20 19:45:42 (6d ago) - - - master 

También le permite almacenar properties personalizadas para cada twig, por ejemplo, identificación del ticket, estado, todos, y filtrar la list de sucursales de acuerdo con estas properties. Más información: http://rondevera.github.io/twig/

Para su información, si desea get una list de las sucursales que se han prestado recientemente (en lugar de las que se han comprometido recientemente), puede usar el reflog de git:

 $ git reflog | egrep -io "moving from ([^[:space:]]+)" | awk '{ print $3 }' | head -n5 master stable master some-cool-feature feature/improve-everything 

Vea también: ¿Cómo puedo get una list de las sucursales de git que he revisado recientemente?

Pude hacer reference a los ejemplos anteriores para crear algo que funciona mejor para mí.

git for-each-ref –sort = -committerdate refs / heads / –format = '% (authordate: short)% (color: networking)% (objectname: short)% (color: yellow)% (refname: short )% (color: restablecer) (% (color: verde)% (date de confirmación: relativa)% (color: restablecer)) '

Captura de pantalla de salida

Se me ocurrió el siguiente command (para Git 2.13 y posterior):

 git branch -r --sort=creatordate \ --format "%(creatordate:relative);%(committername);%(refname:lstrip=-1)" \ | grep -v ";HEAD$" \ | column -s ";" -t 

Si no tiene column , puede replace la última línea con

  | sed -e "s/;/\t/g" 

La salida se ve como

 6 years ago Tom Prestn-Werner book 4 years, 4 months ago Parker Moore 0.12.1-release 4 years ago Matt Rogers 1.0-branch 3 years, 11 months ago Matt Rogers 1.2_branch 3 years, 1 month ago Parker Moore v1-stable 12 months ago Ben Balter pages-as-documents 10 months ago Jordon Bedwell make-jekyll-parallel 6 months ago Pat Hawks to_integer 5 months ago Parker Moore 3.4-stable-backport-5920 4 months ago Parker Moore yajl-ruby-2-4-patch 4 weeks ago Parker Moore 3.4-stable 3 weeks ago Parker Moore rouge-1-and-2 19 hours ago jekyllbot master 

Escribí una publicación de blog sobre cómo funcionan las diversas piezas.

Aquí hay otro script que hace lo que hacen todos los otros scripts. De hecho, proporciona una function para tu caparazón.

Su contribución es que extrae algunos colors de su configuration de git (o usa los valores pnetworkingeterminados).

 # Git Branch by Date # Usage: gbd [ -r ] gbd() { local reset_color=`tput sgr0` local subject_color=`tput setaf 4 ; tput bold` local author_color=`tput setaf 6` local target=refs/heads local branch_color=`git config --get-color color.branch.local white` if [ "$1" = -r ] then target=refs/remotes/origin branch_color=`git config --get-color color.branch.remote networking` fi git for-each-ref --sort=committerdate $target --format="${branch_color}%(refname:short)${reset_color} ${subject_color}%(subject)${reset_color} ${author_color}- %(authorname) (%(committerdate:relative))${reset_color}" } 

Según la versión de ilius, pero con la twig actual mostrada con una estrella y en color, y solo mostrando todo lo que no se describe como "meses" o "años" atrás:

 current_branch="$(git symbolic-ref --short -q HEAD)" git for-each-ref --sort=committerdate refs/heads \ --format='%(refname:short)|%(committerdate:relative)' \ | grep -v '\(year\|month\)s\? ago' \ | while IFS='|' read branch date do start=' ' end='' if [[ $branch = $current_branch ]]; then start='* \e[32m' end='\e[0m' fi printf "$start%-30s %s$end\\n" "$branch" "$date" done 

Mi mejor resultado como guión:

 git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)|%(committerdate:iso)|%(authorname)' | sed 's/refs\/heads\///g' | grep -v BACKUP | while IFS='|' read branch date author do printf '%-15s %-30s %s\n' "$branch" "$date" "$author" done 

Aquí está la variación que estaba buscando:

 git for-each-ref --sort=-committerdate --format='%(committerdate)%09%(refname:short)' refs/heads/ | tail -r 

Esa tail -r invierte la list, por lo que la date de commiterdate más reciente es la última.

Tarde a la fiesta aquí. La respuesta aceptada de CML es muy buena, pero si quieres algo más bonito, como una GUI, y tu origen === "github".

Puede hacer clic en "Sucursales" en el repository. o acceda a la URL directamente: https://github.com/ORGANIZATION_NAME/REPO_NAME/branches

Transformo el resultado de la respuesta aceptada al dialog , para darme una list interactiva:

 #!/bin/bash TMP_FILE=/tmp/selected-git-branch eval `resize` dialog --title "Recent Git Branches" --menu "Choose a branch" $LINES $COLUMNS $(( $LINES - 8 )) $(git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short) %(committerdate:short)') 2> $TMP_FILE if [ $? -eq 0 ] then git checkout $(< $TMP_FILE) fi rm -f $TMP_FILE clear 

Guarde como (por ejemplo) ~/bin/git_recent_branches.sh y chmod +x it. Luego git config --global alias.rb '!git_recent_branches.sh' para darme un nuevo command git rb .

Aquí hay un pequeño script que utilizo para cambiar entre las sucursales recientes:

 #!/bin/bash # sudo bash re='^[0-9]+$' if [[ "$1" =~ $re ]]; then lines="$1" else lines=10 fi branchs="$(git recent | tail -n $lines | nl)" branchs_nf="$(git recent-nf | tail -n $lines | nl)" echo "$branchs" # Prompt which server to connect to max="$(echo "$branchs" | wc -l)" index= while [[ ! ( "$index" =~ ^[0-9]+$ && "$index" -gt 0 && "$index" -le "$max" ) ]]; do echo -n "Checkout to: " read index done branch="$( echo "$branchs_nf" | sed -n "${index}p" | awk '{ print $NF }' )" git co $branch clear 

Usando esos dos alias

 recent = for-each-ref --sort=committerdate refs/heads/ --format=' %(color:blue) %(authorname) %(color:yellow)%(refname:short)%(color:reset)' recent-nf = for-each-ref --sort=committerdate refs/heads/ --format=' %(authorname) %(refname:short)' 

Solo llámalo en un git repo y te mostrará las últimas N sucursales (10 por defecto) y un número a un lado cada una. Ingrese el número de la twig y se retira.