是否有一种简单的方法可以删除所有远程对等分支不再存在的跟踪分支?
例子:
分支机构(本地和远程)
主人原始/主起源/bug-fix-a起源/bug-fix-b起源/bug-fix-c
在本地,我只有一个主分支。现在我需要处理bug-fix-a,所以我检查它,处理它,并将更改推到远程。接下来,我对bug-fix-b做同样的操作。
分支机构(本地和远程)
主人bug-fix-abug-fix-b型原始/主起源/bug-fix-a起源/bug-fix-b起源/bug-fix-c
现在我有本地分支机构master,bug-fix-a,bug--fix-b。主分支维护者将把我的更改合并到主分支中,并删除他已经合并的所有分支。
因此,当前状态为:
分支机构(本地和远程)
主人bug-fix-abug-fix-b型原始/主起源/bug-fix-c
现在我想调用一些命令来删除分支(在本例中为bug-fix-a、bug-fix-b),这些分支在远程存储库中不再表示。
它类似于现有命令git remote prune origin,但更类似于git local prune origin。
所有这些都不适合我。我想要一些东西来清除所有跟踪远程分支的本地分支,在源位置,远程分支已被删除(消失)。我不想删除从未设置为跟踪远程分支的本地分支(即:我的本地dev分支)。我还想要一个简单的一行程序,它只使用git或其他简单的CLI工具,而不是编写自定义脚本。我最后使用了一点grep和awk来生成这个简单的命令。
这最终是我的~/.gitconfig:
[alias]
prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -D
这里有一个git-config--global。。。用于轻松将其添加为git prune分支的命令:
git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'
注意:在config命令中,我使用-d选项来gitbranch,而不是-d,正如我在实际配置中所做的那样。我使用-D是因为我不想听到Git抱怨未合并的分支。您可能也需要此功能。如果是这样,只需在config命令末尾使用-D而不是-D。
这里有一个解决方法,我用它来处理鱼壳。在Mac OS X 10.11.5、fish 2.3.0和git 2.8.3上测试。
function git_clean_branches
set base_branch develop
# work from our base branch
git checkout $base_branch
# remove local tracking branches where the remote branch is gone
git fetch -p
# find all local branches that have been merged into the base branch
# and delete any without a corresponding remote branch
set local
for f in (git branch --merged $base_branch | grep -v "\(master\|$base_branch\|\*\)" | awk '/\s*\w*\s*/ {print $1}')
set local $local $f
end
set remote
for f in (git branch -r | xargs basename)
set remote $remote $f
end
for f in $local
echo $remote | grep --quiet "\s$f\s"
if [ $status -gt 0 ]
git branch -d $f
end
end
end
几点注意事项
确保设置正确的base_branch。在本例中,我使用develop作为基本分支,但它可以是任何东西。
这一部分非常重要:grep-v“\(master\|$base_branch\|\*\)”。它确保您不会删除主分支或基本分支。
我使用gitbranch-d<branch>作为额外的预防措施,以便不删除任何尚未与上游或当前HEAD完全合并的分支。
一种简单的测试方法是用echo“将删除$f”替换gitbranch-d$f。
我想我还应该补充一句:使用风险自负!
另一个答案,大量借鉴Patrick的答案(我喜欢这个答案,因为它似乎消除了任何关于去哪儿的歧义),将在git分支输出中匹配),但添加了*nix弯曲。
最简单的形式是:
git branch --list --format \
"%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)" \
| xargs git branch -D
我的路径上有一个git-gone脚本:
#!/usr/bin/env bash
action() {
${DELETE} && xargs git branch -D || cat
}
get_gone() {
git branch --list --format \
"%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)"
}
main() {
DELETE=false
while [ $# -gt 0 ] ; do
case "${1}" in
(-[dD] | --delete) DELETE=true ;;
esac
shift
done
get_gone | action
}
main "${@}"
注:--format选项似乎很新;我需要将git从2.10.something升级到2.16.3才能获得它。
编辑:修改为包含参考名的建议:来自Benjamin W。
NB2-我只在bash中进行了测试,因此有了hashbang,但可能可以移植到sh。