我需要从我们的远程存储库中删除旧的和未维护的分支。我正在尝试找到一种方法来列出远程分支的上次修改日期,但我做不到。
有没有一种简单的方法可以这样列出远程分支?
我需要从我们的远程存储库中删除旧的和未维护的分支。我正在尝试找到一种方法来列出远程分支的上次修改日期,但我做不到。
有没有一种简单的方法可以这样列出远程分支?
Answers:
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
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'
注:n8tr的答案的基础上,git for-each-ref refs/heads
更干净。而且更快。
另请参阅“ 仅命名选项git branch --list
? ”。
- 优先使用现代
$(command substitution)
语法而不是过时的反引号语法。
(我在2014年用“ shell编程和shell编程有什么区别?$(command)
`command`
” 说明了这一点。)
- 不要阅读带有的行
for
。- 可能切换到
git for-each-ref refs/remote
获取机器可读格式的远程分支名称
/json
到任何commandlinefu.com URL 的末尾,并且将所有命令作为JSON获得。
这是我用的:
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”,以获取最新信息。
authordate
(似乎是第一次创建分支时?)。如果更改authordate
为,committerdate
那么您将在每个分支中看到最近提交的日期。像这样:git for-each-ref --sort='-committerdate:iso8601' --format=' %(committerdate:iso8601)%09%(refname)' refs/heads
建立在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/--'
然后,一个简单的“ git branchdate”将为您打印列表。
--format='%(authordate)%09%(objectname:short)%09%(refname)'
它也获取每个分支的短哈希。
| tac
,只是--sort='authordate'
代替-authordate
这也是我在对此进行回顾之后想到的。
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-merged
在识别可以轻松删除的分支时很有用。
根据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 "|"
。(您可以使用任何东西作为分隔符,只要它在其余的输出中是您所不期望的即可。)
我的第二个变种非常hacky,但是我确实想要一种仍然可以像“分支”命令那样显示“这是您当前正在使用的分支”的指示器。
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
是处理脚本的脚本友好方式。您必须运行一次symbolic-ref才能获取当前分支。
我做了一个简单的别名,不确定这是否是正确的要求,但是很简单
我这样做是因为我想列出所有分支,而不仅仅是我的本地分支,以上命令仅列出这些分支
alias git_brs="git fetch && git branch -av --format='\''%(authordate)%09%(authordate:relative)%09%(refname)'\'"
您可以通过管道grep origin
仅获取来源
该列表列出了所有分支以及最近修改的日期,可帮助我确定我应该拉哪个版本的最新版本
这导致以下显示类型
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
尝试让我知道是否有帮助
或者您可以使用我的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++;
}
?>
您可以将以下功能添加到您的bash_profile中,以使其变得更容易。
在Git存储库中的用法:
branch
打印所有本地分支branch -r
打印所有远程分支功能:
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中,以下内容显示了已合并且已存在至少两周的远程分支(该author: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}