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?
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'
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.
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
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 ...
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]
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
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.)
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 localesbranch -r
imprime toutes les branches distantesUne 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
}
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++;
}
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}