web-dev-qa-db-fra.com

Liste de chaque branche et la date de sa dernière révision dans git

Je dois supprimer les branches anciennes et non entretenues de notre référentiel distant. J'essaie de trouver un moyen de répertorier les branches distantes par leur dernière date de modification, et je ne peux pas.

Quelqu'un connaît-il un moyen facile de répertorier les succursales distantes de cette façon?

127
Roni Yaniv

commandlinef a 2 propositions intéressantes:

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

ou:

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

C'est pour les branches locales, dans une syntaxe Unix. En utilisant git branch -r, vous pouvez également afficher les branches distantes:

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 mentionne dans les commentaires que zsh nécessite des échappements pour l'expression sed:

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 ajoute dans les commentaires :

Si vous voulez l'ajouter à votre zshrc, l'échappement suivant est nécessaire.

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 plusieurs lignes:

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'
161
VonC

Voici ce que j'utilise:

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

Voici la sortie:

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

Pour les succursales distantes, utilisez simplement "refs/remotes" au lieu de "refs/heads":

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

En s'appuyant sur la réponse de l8tr, si vous êtes également intéressé par le dernier auteur de la branche, et si vous disposez de l'outil "colonne", vous pouvez utiliser:

git for-each-ref --sort='-committerdate:iso8601' --format='%(committerdate:relative)|%(refname:short)|%(committername)' refs/remotes/ | column -s '|' -t

Ce qui vous donnera:

21 minutes ago  refs/remotes/a        John Doe
6 hours ago     refs/remotes/b        Jane Doe
6 days ago      refs/remotes/master   John Doe

Vous voudrez peut-être appeler "git fetch --Prune" avant d'avoir les dernières informations.

103
ocroquette

En partant de Olivier Croquette , 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 partager le script avec votre équipe. Voici un exemple pour ajouter juste 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 le faire pour obtenir une liste de branches locales bien formatée et triée:

git branches
20
n8tr

Juste pour ajouter au commentaire de @VonC, prenez votre solution préférée et ajoutez-la à votre liste d'alias ~/.gitconfig pour plus de commodité:

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

Ensuite, une simple "date de branchement git" imprime la liste pour vous ...

19
yngve

Voici ce que j'ai trouvé après avoir également examiné 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

Le PREV_REF la vérification consiste à supprimer les doublons si plusieurs branches pointent vers le même commit. (Comme dans la branche locale qui existe également dans la télécommande.)

NOTEZ que par la demande OP, git branch --merged et git branch --no-merged sont utiles pour identifier les branches qui peuvent être facilement supprimées. [ https://git-scm.com/docs/git-branch]

4
go2null

Triées à distance branches et la dernière date de validation pour chaque branche.

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
3
shweta

J'ai fait deux variantes, basées sur la réponse de VonC.

Ma première 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 "|"

Cela gère les branches locales et distantes (-a), gère l'état de tête détachée (la commande sed plus longue, bien que la solution soit un peu grossière - elle remplace simplement les informations de branche détachée par le mot-clé HEAD), ajoute le sujet de validation ( % s), et met les choses en colonnes via des caractères de canal littéraux dans la chaîne de format et en passant le résultat final à column -t -s "|". (Vous pouvez utiliser n'importe quoi comme séparateur, tant que c'est quelque chose que vous n'attendez pas dans le reste de la sortie.)

Ma deuxième variante est assez hacky, mais je voulais vraiment quelque chose qui a toujours un indicateur de "c'est la branche sur laquelle vous êtes actuellement" comme le fait la commande branch.

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 "|"

Cela transforme le * qui marque la branche actuelle en un mot-clé, et lorsque le corps de la boucle voit le mot-clé, il définit à la place un indicateur et ne produit rien. L'indicateur est utilisé pour indiquer qu'une autre mise en forme doit être utilisée pour la ligne suivante. Comme je l'ai dit, totalement hacky, mais ça marche! (Surtout. Pour une raison quelconque, ma dernière colonne est dépassée sur la ligne de branchement actuelle. Mais je devrais vraiment recommencer à faire du travail réel au lieu de peaufiner cela davantage.)

1
benkc

Voici une fonction que vous pouvez ajouter à votre bash_profile pour vous faciliter la tâche.

Utilisation dans un référentiel git:

  • branch imprime toutes les branches locales
  • branch -r imprime toutes les branches distantes

Une fonction:

branch() {
   local pattern="s/^..//"
   local arg=""
   if [[ $@ == "-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
enderland

Ou vous pouvez utiliser mon script php https://Gist.github.com/2780984

#!/usr/bin/env php
<?php
$local = exec("git branch | xargs $1");
$lines = explode(" ", $local);
$limit = strtotime("-2 week");
$exclude = array("*", "master");
foreach ($exclude as $i) {
    $k = array_search($i, $lines);
    unset($lines[$k]);
}
$k = 0;
foreach ($lines as $line) {
    $output[$k]['name'] = $line;
    $output[$k]['time'] = exec('git log '.$line.' --pretty=format:"%at" -1');
    if ($limit>$output[$k]['time']) {       
        echo "This branch should be deleted $line\n";
        exec("git branch -d $line");
    }
    $k++;
}
0

Dans Powershell, montre les branches de la télécommande qui ont déjà fusionné et qui ont au moins deux semaines. (auteur: le format relatif commence à afficher les semaines au lieu des jours à deux semaines)

$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}
0
Dave Neeley