2010-03-25 13 views
98

Ho bisogno di eliminare i rami vecchi e non più mantenuti dal nostro repository remoto. Sto cercando di trovare un modo con cui elencare i rami remoti alla loro ultima data di modifica, e non posso.Elenco di ogni filiale e data dell'ultima revisione in git

Qualcuno sa di un modo semplice per elencare le filiali remote in questo modo?

+1

Eventuali duplicati di [Come posso ottenere un elenco di rami Git, ordinato dai più recenti commettere?] (Http://stackoverflow.com/questions/5188320/how-can-i-get-a-list-of-git-branches-ordered-by-most-recent-commit) –

+2

Le risposte a: http://stackoverflow.com/questions/5188320/ how-can-i-get-a-list-of-git-branches-ordered-by-most-recent-commit sono tutti migliori delle risposte qui –

risposta

133

commandlinefu ha 2 proposte interessanti:

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 

che è per filiali locali, in una sintassi Unix. Utilizzando git branch -r, è possibile visualizzare in modo simile filiali remote:

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 menzioni in the comments che zsh richiede fughe per la sed espressione:

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 aggiunge in the comments:

Se tu vuoi per aggiungerlo al tuo zshrc è necessaria la seguente fuga.

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' 

In più righe:

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

grazie! proprio quello di cui avevo bisogno! –

+11

+1 per avermi fatto conoscere commandlinefu! – hasen

+1

@hansen j: interessante, non è vero? È stato lanciato pochi mesi dopo l'uscita pubblica di Stack Overflow (http://codeinthehole.com/archives/16-Current-pet-project-Command-Line-Fu.html) ed è stato in qualche modo ispirato a SO. Vedi anche http://www.commandlinefu.com/commands/tagged/67/git per ulteriori informazioni su git commandlinefu;) – VonC

17

Giusto per aggiungere al commento di @VonC, prendere la soluzione preferita e aggiungerla al l'alias ~/.gitconfig per comodità:

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

Poi un semplice "git branchdate" stampa la lista per voi ...

+3

+1 per mostrare come usarlo con .gitconfig! Inoltre ho modificato la stringa di formato in: '--format = '% (authordate)% 09% (objectname: short)% 09% (refname)'' che ottiene anche l'hash breve di ogni ramo. –

+0

Bello. Aggiungerei "| tac" alla fine per ottenerlo ordinato in ordine inverso in modo che i rami appena toccati siano rapidamente visibili. – Ben

+0

Non è necessario '| tac', solo '--sort = 'authordate'' invece di' -authordate' –

67

Ecco quello che io uso:

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

Questa è l'uscita:

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 

Per filiali remote, basta utilizzare "refs/telecomandi" invece di "refs/teste":

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

Si consiglia di chiamare "git fetch --prune" prima di avere t lui ultime informazioni.

+4

Bel uso di for-each-ref e delle opzioni di formato. +1. Sembra più facile dei comandi che faccio riferimento nella mia risposta. – VonC

+1

tweaking un po ': ------- git for-each-ref --sort =' - authordate: iso8601 '--format ='% (authordate: relative)% 09% (refname: short) 'refs/teste ------- ti dà una data relativa ed elimina i ref/heads – n8tr

+0

Per quelli a cui non è immediatamente ovvio, penso che questo mostri informazioni. rigorosamente per le filiali locali. – hBrent

13

costruzione al largo di Olivier Croquette, Mi piace usare una data relativa e abbreviando il nome del ramo come questo:

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

che garantisce un modo di uscita:

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 

vi consiglio di fare un file bash per l'aggiunta tutti i tuoi alias preferiti e poi condividere lo script con il tuo team. Ecco un esempio di aggiungere solo questo:

#!/bin/sh 

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

allora si può solo fare questo per ottenere un elenco filiale locale ben formattato e ordinati:

git branches 
+0

Bel formato ottimizzato. +1 – VonC

+0

Bella variazione. +1 – ocroquette

1

ho fatto due varianti, in base alla risposta del VonC.

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

Questo gestisce locali & rami remoti (-a), gestisce stato distaccato testa (il comando più sed, anche se la soluzione è tipo di greggio - solo sostituisce la informazioni sulla diramazione staccata con la parola chiave HEAD), aggiunge nell'oggetto di commit (% s) e inserisce le cose in colonne tramite caratteri letterali del pipe nella stringa di formato e passando il risultato finale a column -t -s "|". (Puoi usare qualsiasi cosa come separatore, purché sia ​​qualcosa che non ti aspetti dal resto dell'output.)

La mia seconda variante è abbastanza hacky, ma volevo davvero qualcosa che avesse ancora un indicatore di " questo è il ramo su cui stai attualmente "come fa il comando del ramo.

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

Questo trasforma il * che segna il ramo corrente in una parola, e quando il corpo del ciclo vede la parola si stabilisce invece una bandiera e uscite nulla. Il flag viene utilizzato per indicare che è necessario utilizzare una formattazione alternativa per la riga successiva. Come ho detto, totalmente hacky, ma funziona! (Per lo più. Per qualche motivo il mio ultima colonna è sempre rientrata sulla linea ramo corrente. Ma io in realtà dovrebbe tornare a fare il lavoro vero e proprio, invece di tweaking questo di più.)

+0

Sfortunatamente le informazioni nella risposta VonCs non sono un ottimo fondamento per lo scripting. Vedi qui http://git-blame.blogspot.com/2013/06/checking-current-branch-programatically.html –

+0

Hmm. Questo mostra un modo per ottenere il nome del ramo corrente, se ha un nome. Esiste un modo [preferito] per ottenere un elenco di filiali a misura di macchina? (E un modo per distinguere il ramo corrente, o direttamente da quell'output o attraverso in qualche modo chiedere git "è questo lo stesso ref di HEAD?") – benkc

+0

'git for-each-ref' è il modo script-friendly di elaborare i rami. Dovresti eseguire il riferimento simbolico una volta per ottenere il ramo attuale. –

2

In ordine remota rami e l'ultima data di impegnarsi per ogni ramo

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

Grazie per aver risposto alla domanda OP relativa al telecomando. – arcseldon

2

Ecco cosa ho trovato dopo aver anche esaminato 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 

Il controllo PREV_REF è rimuovere duplicati se più di una punti di ramificazione allo stesso commettono. (Come nel ramo locale che esiste anche nel telecomando.)

NOTA che per la richiesta OP, git branch --merged e git branch --no-merged sono utili per identificare quali rami possono essere facilmente eliminati. [https://git-scm.com/docs/git-branch]

0

Ecco una funzione che è possibile aggiungere a bash_profile per semplificare la procedura.

utilizzo quando in un repository git:

  • branch stampa tutte le sezioni locali
  • branch -r stampa tutti i rami remoti

Funzione:

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

In Powershell, mostra rami sul telecomando che sono già stati uniti d almeno due settimane di vita. (Autore: relative formato inizia a visualizzare settimane invece di giorni a due settimane)

$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} 
Problemi correlati