web-dev-qa-db-fra.com

Comment puis-je obtenir une liste des branches Git, classées par le dernier commit?

Je souhaite obtenir une liste de toutes les branches dans un référentiel Git avec les branches "les plus récentes" en haut, où la branche "la plus récente" est celle qui a été utilisée le plus récemment (et a donc plus de chances de l'être). Je veux faire attention à).

Existe-t-il un moyen d'utiliser Git pour (a) trier la liste des branches par le dernier commit ou (b) obtenir une liste des branches avec la date de dernière validation de chacun, dans un format lisible par machine?

Dans le pire des cas, je pourrais toujours exécuter git branch pour obtenir une liste de toutes les branches, analyser sa sortie, puis git log -n 1 branchname --format=format:%ci pour chacune d’elles, afin d’obtenir la date de validation de chaque branche. Mais cela fonctionnera sous Windows, où la mise en place d'un nouveau processus est relativement onéreuse. Le lancement de l'exécutable Git une fois par branche risque donc d'être lent s'il y a beaucoup de branches. Est-il possible de faire tout cela avec une seule commande?

984
Joe White

Utilisez l’option --sort=-committerdate de git for-each-ref ;

Egalement disponible depuis Git 2.7.0 pour git branch :

Utilisation basique:

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

Résultat:

Result

Utilisation avancée:

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

Résultat:

Result

1407
Jakub Narębski

Liste des noms de branches git, classés par le plus récent commit…

S'agissant de la réponse de Jakub et du conseil de Joe, le texte suivant supprimera les "références/têtes /" afin que la sortie affiche uniquement les noms des branches:


Commander:

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

Résultat:

 recent git branches

113
Beau Smith

Voici le code optimal, qui combine les deux autres réponses:

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

Voici une commande simple qui répertorie toutes les branches avec les derniers commits:

git branch -v

Pour commander par le dernier commit, utilisez

git branch -v --sort=committerdate

Source: http://git-scm.com/book/fr/Git-Branching-Branch-Management

68
user1682406

J'avais aussi besoin de couleurs, de balises et de références distantes sans doublons:

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]++'

Parce que citer peut être difficile, voici l'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'"]++'"
36
estani

J'ai pu citer les exemples ci-dessus pour créer quelque chose qui me convient le mieux.

git pour-each-ref --sort = -committerdate refs/heads / --format = '% (authordate: short)% (couleur: rouge)% (objectname: short)% (couleur: jaune)% (refname: court)% (couleur: reset). (% (couleur: vert)% (committerdate: relative)% (couleur: réinitialiser)) '

 Screenshot of Output

24
Andy

Les autres réponses ne semblent pas autoriser le passage de -vv pour obtenir une sortie commentée.

Donc, voici une ligne qui trie git branch -vv par date de validation, en préservant la couleur, 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 vous souhaitez également imprimer la date de validation, vous pouvez utiliser cette version à la place:

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-

Exemple de sortie:

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

C'est probablement plus lisible, divisé en plusieurs lignes:

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-

Cela devrait également fonctionner avec d'autres arguments de git branch, par exemple. -vvr pour répertorier les branches de suivi à distance, ou -vva pour répertorier les branches de suivi à distance et locales.

23
John Mellor

git 2.7 (T4 2015) introduira le tri des branches en utilisant directement git branch:
Voir commit aa3bc55 _, commit aedcb7d , commit 1511b22 , commit f65f139 , ... (23 sept. 2015), commit aedcb7d , commit 1511b22 , commit ca41799 (24 sept. 2015), et commit f65f139 , ... (23 sept. 2015) de _ { Karthik Nayak (KarthikNayak) } _.
(Fusionnée par Junio ​​C Hamano - gitster - à commit 7f11b48 , 15 octobre 2015)

En particulier, commit aedcb7d :

branch.c: utilisez les API 'ref-filter'

Assurez-vous que 'branch.c' utilise les API 'ref-filter' pour effectuer une itération dans le tri des références. Cela supprime la plupart du code utilisé dans 'branch.c' en le remplaçant par Par des appels à la bibliothèque 'ref-filter'.

Il ajoute l'option --sort=<key> :

Trier en fonction de la clé donnée.
Préfixe - pour trier par ordre décroissant de la valeur. 

Vous pouvez utiliser l'option --sort=<key> plusieurs fois, auquel cas la dernière clé devient la clé primaire. 

Les clés prises en charge sont les identiques à celles de git for-each-ref .
L'ordre de tri par défaut est le tri basé sur le nom de référence complet (avec le préfixe refs/...). Ceci répertorie d'abord HEAD détaché (le cas échéant), puis les branches locales et enfin les branches distantes.

Ici:

git branch --sort=-committerdate 

Ou (voir ci-dessous avec Git 2.19)

# if you are sure to /always/ want to see branches ordered by commits:
git config --global branch.sort -committerdate
git branch

Voir aussi commit 9e46833 (30 octobre 2015) de Karthik Nayak (KarthikNayak) }.
Aidé par: Junio ​​C Hamano (gitster) }.
(Fusionnée par Junio ​​C Hamano - gitster - à commit 415095f , 3 nov. 2015)

Lors du tri selon les valeurs numériques (par exemple, --sort=objectsize), il n’existe aucune comparaison de remplacement lorsque les deux références contiennent la même valeur. Cela peut entraîner des résultats inattendus (par exemple, l'ordre des références de liste avec des valeurs égales ne peut pas être prédéterminé), comme l'a souligné Johannes Sixt ( $ gmane/280117 ).

Donc, repli sur la comparaison alphabétique basée sur le nom de référence chaque fois que l'autre critère est égal.

$ git branch --sort=objectsize

*  (HEAD detached from fromtag)
      branch-two
      branch-one
      master

Avec Git 2.19, l'ordre de tri peut être défini par défaut.
git branch supporte une config branch.sort, comme git tag, qui possédait déjà une config tag.sort.
Voir commit 560ae1c (16 août 2018) de Samuel Maftoul (``) }.
(Fusion de Junio ​​C Hamano - gitster - à commit d89db6f , 27 août 2018)

branch.sort:

Cette variable contrôle l'ordre de tri des branches lorsqu'elles sont affichées par git-branch.
Sans l'option "--sort=<value>" fournie, la valeur de cette variable sera utilisée par défaut.


Pour répertorier les branches distantes, utilisez git branch -r --sort=objectsize. L'indicateur -r fait qu'il répertorie les branches distantes au lieu des branches locales.

21
VonC

J'aime utiliser une date relative et raccourcir le nom de la branche comme ceci:

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

Ce qui vous donne une sortie:

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

Je recommande de créer un fichier bash pour ajouter tous vos alias préférés, puis de partager le script avec votre équipe. Voici un exemple pour ajouter seulement celui-ci: 

#!/bin/sh

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

Ensuite, vous pouvez simplement faire ceci pour obtenir une liste de branches locales joliment formatée et triée:

git branches

Mise à jour: .__ Faites ceci si vous voulez colorer:

#!/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)$|$"
19
n8tr

Ajoute de la couleur (puisque pretty-format n'est pas 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"
11
epylinkn

A partir de la version 2.19, vous pouvez simplement:

git branch --sort=-committerdate

Vous pouvez également:

git config branch.sort -committerdate

Ainsi, chaque fois que vous listez des branches dans le référentiel actuel, elles seront triées par committerdate.

Si vous voulez chaque fois que vous listez des branches, vous voulez qu'elles soient triées par comitterdate:

git config --global branch.sort -committerdate

Avertissement: je suis l'auteur de cette fonctionnalité dans git, je l'ai implémentée lorsque j'ai vu cette question.

9
user801247

J'ai eu le même problème, alors j'ai écrit une gemme Ruby appelée Twig . Il répertorie les branches par ordre chronologique (le plus récent en premier) et peut également vous permettre de définir un âge maximal afin de ne pas répertorier toutes les branches (si vous en avez beaucoup). Par exemple:

$ 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

Il vous permet également de stocker des propriétés personnalisées pour chaque branche, par exemple, l'id du ticket, l'état, les tâches à effectuer et de filtrer la liste des branches en fonction de ces propriétés. Plus d'infos: http://rondevera.github.io/twig/

8
Ron DeVera

Je suis arrivé avec la commande suivante (pour Git 2.13 et versions ultérieures):

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

Si vous n'avez pas column, vous pouvez remplacer la dernière ligne par

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

La sortie ressemble à

6 years ago             Tom Preston-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

J'ai écrit un article de blog sur le fonctionnement des différentes pièces.

8
bdesham

Pour votre information, si vous souhaitez obtenir une liste des extraites dernières branches (par opposition à celles récemment validées), vous pouvez utiliser le compte rendu de git:

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

Voir aussi: Comment puis-je obtenir une liste des branches git que j'ai récemment extraites?

7
Jordan Brough

Voici un autre script qui fait comme tous les autres scripts. En fait, il fournit une fonction à votre shell.

Sa contribution est qu’il tire des couleurs de votre configuration git (ou utilise des valeurs par défaut).

# 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 red`
    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}"
}
4
joeytwiddle

Voici un petit script que j'utilise pour basculer entre les branches récentes:

#!/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

Utiliser ces deux 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)'

Appelez simplement cela dans un dépôt git et il vous montrera les N dernières branches (10 par défaut) et un numéro à part. Entrez le numéro de la branche et il vérifie:

 enter image description here

3
Agus Arias

Basé sur la version de ilius, mais avec la branche actuelle avec une étoile et une couleur, et ne montrant que ce qui n’est pas décrit comme "mois" ou "années":

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
3
Mark Lodato

Mon meilleur résultat en tant que script:

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
2
saeedgnu

Normalement, nous considérons les branches distantes récemment. Alors essayez ceci

git fetch
git for-each-ref --sort=-committerdate refs/remotes/Origin
1
Victor Choy

En retard à la fête ici. La réponse CML acceptée est géniale, mais si vous voulez quelque chose de plus joli, comme une interface graphique, et votre origine === "github". 

Vous pouvez cliquer sur "Branches" dans le repo. ou appuyez sur l'URL directe: https://github.com/ORGANIZATION_NAME/REPO_NAME/branches

1
jahrichie

git branch --sort=-committerdate | head -5

Pour tous ceux qui sont intéressés à ne faire que classer les 5 meilleurs noms de branches en fonction de la date de publication 

1
vardin

Voici la variation que je cherchais:

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

Ce tail -r inverse la liste de sorte que la plus récente commiterdate soit la dernière.

1
Ben

Je sais qu'il y a déjà beaucoup de réponses, mais voici mes deux sous pour un simple alias (j'aime avoir ma branche la plus récente en bas):

[alias]
        br = !git branch --sort=committerdate --color=always | tail -n15
[color "branch"]
        current = yellow
        local = cyan
        remote = red

Cela vous donnera un bon aperçu de vos 15 dernières succursales, en couleur, avec votre succursale actuelle mise en surbrillance (et son astérisque).

1
Tom

Je transfère le résultat de la réponse acceptée dans dialog, pour me donner une liste interactive:

#!/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

Enregistrer sous (par exemple) ~/bin/git_recent_branches.sh et chmod +x le. Puis git config --global alias.rb '!git_recent_branches.sh' pour me donner une nouvelle commande git rb.

1
John Delaney

Git v2.19 introduit l'option branch.sort config (voir branch.sort ).

Donc, git branch triera par date de committer (desc) par défaut avec

# gitconfig
[branch]
    sort = -committerdate     # desc

scénario:

$ git config --global branch.sort -committerdate

Mettre à jour:

Alors,

$ git branch
* dev
  master
  _

et

$ git branch -v
* dev    0afecf5 Merge branch 'oc' into dev
  master 652428a Merge branch 'dev'
  _      7159cf9 Merge branch 'bashrc' into dev
0
hIpPy

git for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))' c'est ce dont vous avez besoin

0
ChunkCoder