我需要从我们的远程代码库中删除旧的且无人维护的分支。我正在尝试找到一种按其最后修改日期列出远程分支的方法,但我找不到。
有没有简便的方法以这种方式列出远程分支?
我需要从我们的远程代码库中删除旧的且无人维护的分支。我正在尝试找到一种按其最后修改日期列出远程分支的方法,但我找不到。
有没有简便的方法以这种方式列出远程分支?
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 --color=always -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
迈克尔·福雷斯特(Michael Forrest)在评论中提到,zsh需要对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添加了在评论中:
如果您想将其添加到您的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 refs/heads
的n8tr 的 answer 更加简洁。而且速度更快。git branch --list
?"。(我在2014年通过 "What is the difference between
- 使用现代的
$(command substitution)
语法优先过时的反引号语法。
$(command)
and `command`
in shell programming?" 来说明这一点)
- 不要阅读带有
for
的行。- 可能需要切换到
git for-each-ref refs/remote
以获取机器可读格式的远程分支名称
git branch | perl -pe s\/\^\.\.\/\/
中的每一个k,执行以下操作:echo -e git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1
\t$k; 然后按照倒序排序。 - Michael Forrest这是我使用的:
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
在n8tr的答案的基础上,如果您还对分支上的最后一位作者感兴趣,并且如果您有“列”工具可用,您可以使用以下方法:
git for-each-ref --sort='-committerdate:iso8601' --format='%(committerdate:relative)|%(refname:short)|%(committername)' refs/remotes/ | column -s '|' -t
这将给你:
21 minutes ago refs/remotes/a John Doe
6 hours ago refs/remotes/b Jane Doe
6 days ago refs/remotes/master John Doe
您可能希望在执行命令之前调用 git fetch --prune
以获取最新信息,或者添加带有特定颜色的格式化输出语句 %(color:<color>)
来显示某些字段。
authordate
对分支进行排序和列出(似乎是分支最初创建的时间?)。如果您将authordate
更改为committerdate
,则将在每个分支中看到最近提交的日期。就像这样:git for-each-ref --sort='-committerdate:iso8601' --format=' %(committerdate:iso8601)%09%(refname)' refs/heads
- Logan Besecker在 Olivier Croquette 的基础上,我喜欢使用相对日期并缩短分支名称,就像这样:
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
我建议创建一个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 ' ------------------------------------------------------------'"
然后,您可以执行以下操作,以获得格式良好且已排序的本地分支列表:
git branches
补充一下 @VonC 的评论,为了方便起见,将您喜欢的解决方案添加到您的 ~/.gitconfig 别名列表中:
[alias]
branchdate = !git for-each-ref --sort='-authordate' --format='%(refname)%09%(authordate)' refs/heads | sed -e 's-refs/heads/--'
--format='%(authordate)%09%(objectname:short)%09%(refname)'
,它还会获取每个分支的短哈希。 - Noah Sussman| tac
,只需使用 --sort='authordate'
替代 -authordate
即可。 - Kristján在查看此问题后,我总结出以下内容:
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
是用来去除重复的检查,如果有多个分支指向同一个提交,则使用该检查。(例如本地分支在远程分支中也存在。)git branch --merged
和git branch --no-merged
对于识别可以轻松删除的分支非常有用。已排序的远程分支和每个分支的最后提交日期。
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
Wed Feb 4 23:21:56 2019 +0230 8 days ago refs/heads/foo
Tue Feb 3 12:18:04 2019 +0230 10 days ago refs/heads/master
Mon Feb 9 12:19:33 2019 +0230 4 days ago refs/heads/bar
Wed Feb 11 16:34:00 2019 +0230 2 days ago refs/heads/xyz
Tue Feb 3 12:18:04 2019 +0230 10 days ago refs/remotes/origin/HEAD
Mon Feb 9 12:19:33 2019 +0230 4 days ago refs/remotes/origin/foo
Tue Feb 3 12:18:04 2019 +0230 10 days ago refs/remotes/origin/master
Tue Feb 3 12:18:04 2019 +0230 10 days ago refs/remotes/origin/bar
Tue Feb 3 12:18:04 2019 +0230 10 days ago refs/remotes/origin/xyz
试一试,如果有帮助请告诉我,愉快地使用 Git 吧
我根据VonC的回答制作了两个版本。
我的第一个版本:
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 "|"
-a
),处理分离头状态(使用更长的sed命令,虽然解决方案有点粗糙——它只是用关键字HEAD替换了分离的分支信息),添加提交主题(%s),并通过格式字符串中的文字管道字符将结果放入列中,并将最终结果传递给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 "|"
*
转换为关键字,当循环体看到该关键字时,它会设置一个标志并不输出任何内容。该标志用于指示下一行应使用替代格式。就像我说的那样,这完全是hacky的,但它可以工作!(大多数情况下。由于某种原因,我的最后一列在当前分支线上被向外缩进了。)git for-each-ref
是处理分支的脚本友好方式。您需要运行一次符号引用以获取当前分支。 - Andrew Cauthor:relative
格式在两周后开始显示周数而非天数):$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}
git log
替换git show
):for k in $(git branch -a | sed -e 's/^..//' | grep -v -- '->'); \
do echo -e $(git log -1 --pretty=format:"%ci %cr" $k) \
\\t$k; done | sort -r