在git中列出每个分支及其最后修订的date

我需要从我们的远程回购中删除旧的和无人维护的分支。 我试图find一种方式来列出远程分支的最后修改date,我不能。

有人知道用这种方法列出远程分支的简单方法吗?

commandlinefu有两个有趣的命题:

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 

要么:

 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 

这是针对本地分支的,使用Unix语法。 使用git branch -r ,你可以类似地显示远程分支:

 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 

迈克尔·福雷斯特 在评论中提到,zsh需要用于sedexpression式的转义:

 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补充说 :

如果你想添加你的zshrc,需要下面的转义。

 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' 

在多行中:

 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' 

这是我使用的:

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

这是输出:

 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 

对于远程分支,只需使用“refs / remotes”而不是“refs / heads”:

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

您可能需要先调用“git fetch –prune”以获取最新信息。

只要添加到@VonC的评论,采取您的首选解决scheme,并将其添加到您的〜/ .gitconfig别名列表为方便起见:

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

然后,一个简单的“git branchdate”打印出你的列表…

从Olivier Croquette开始 ,我喜欢用相对的date和缩短分支的名字,像这样:

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

哪个给你输出:

 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 

我build议创build一个bash文件来添加所有你喜欢的别名,然后把脚本分享给你的团队。 以下是添加这个的一个例子:

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

然后你可以做到这一点,以获得一个很好的格式和sorting的本地分支列表:

 git branches 

sorting远程分支和每个分支的最后提交date。

 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 

这也是我在回顾这个之后想到的。

 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 

如果多个分支指向同一个提交,则PREV_REF检查将删除重复项。 (就像在远程存在的本地分支一样)。

注意,根据OP请求, git branch --merged git branch --no-mergedgit branch --no-merged在识别哪些分支可以被轻易删除时很有用。 [ https://git-scm.com/docs/git-branch%5D

我根据VonC的回答做了两个变种。

我的第一个变种:

 for k in `git branch -a | sed -es/^..// -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 "|" 

这处理本地和远程分支(-a),处理分离头状态(较长的sed命令,虽然解决scheme是粗俗的 – 它只是用关键字HEADreplace分离的分支信息),添加在提交主题%s),并通过格式string中的文字pipe道字符将东西放入列中,并将最终结果传递给column -t -s "|" 。 (你可以使用任何东西作为分隔符,只要这是你在其他输出中不期望的东西。)

我的第二个变种是相当黑客,但我真的想要一个仍然有一个指标“这是你现在的分支”像分支命令一样。

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

这将标记当前分支的*变成一个关键字,当循环体看到关键字时,它将设置一个标志并不输出任何内容。 该标志用于指示下一行应使用备用格式。 就像我说的,完全哈克,但它的作品! (主要是,由于某种原因,我最后一列在当前分支行上已经越过了,但我真的应该回去做实际的工作,而不是调整这些。)

或者你可以使用我的PHP脚本https://gist.github.com/2780984

这里有一个函数可以添加到你的bash_profile中,以使这更容易。

在git仓库中的用法:

  • branch打印所有本地分行
  • branch -r打印所有远程分支

function:

 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 } 

在Powershell中,在已经合并且至less两个星期前的远程显示分支。 (作者:相对格式开始在两周内显示星期而不是几天)

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