如何删除已合并的分支?我可以一次删除所有分支,而不是逐个删除每个分支吗?
当前回答
如果您想删除已合并到当前所在分支的所有本地分支,那么我根据前面的回答提出了一个安全的命令:
git branch --merged | grep -v \* | grep -v '^\s*master$' | xargs -t -n 1 git branch -d
此命令不会影响当前分支或主分支。它还将使用xargs的-t标志告诉您它在做什么。
其他回答
我已经用亚当的答案很多年了。也就是说,在某些情况下,它的行为并没有达到我的预期:
包含单词“master”的分支被忽略,例如“notmaster”或“masterful”,而不仅仅是master分支包含单词“dev”的分支被忽略,例如“dev test”,而不仅仅是dev分支删除可从当前分支的HEAD(即,不一定是主分支)访问的分支在分离HEAD状态下,删除当前提交中可访问的每个分支
1和2很容易解决,只需更改正则表达式。3取决于所需内容的上下文(即仅删除尚未合并到主分支或当前分支的分支)。如果您无意中在分离的HEAD状态下运行,4可能会造成灾难(尽管可以使用git-relog恢复)。
最后,我希望这一切都在一个不需要单独(Bash|Ruby|Python)脚本的一行中。
TL;博士
创建一个接受可选-f标志的git别名“sweep”:
git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'
并调用它:
git sweep
or:
git sweep -f
长而详细的答案
对我来说,创建一个带有一些分支和提交的git repo示例来测试正确的行为是最简单的:
通过一次提交创建新的git repo
mkdir sweep-test && cd sweep-test && git init
echo "hello" > hello
git add . && git commit -am "initial commit"
创建一些新分支
git branch foo && git branch bar && git branch develop && git branch notmaster && git branch masterful
git branch --list
酒吧发展食品*船长,船长有驾驭能力的非主人翁
期望的行为:选择所有合并的分支,但主分支、开发分支或当前分支除外
原始正则表达式缺少分支“masterful”和“notmaster”:
git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"
酒吧
使用更新的正则表达式(现在不包括“develop”而不是“dev”):
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
酒吧有驾驭能力的非主人翁
切换到分支foo,进行新的提交,然后根据foo签出新的分支foobar:
echo "foo" > foo
git add . && git commit -am "foo"
git checkout -b foobar
echo "foobar" > foobar
git add . && git commit -am "foobar"
我当前的分支是foobar,如果我重新运行上面的命令来列出我要删除的分支,即使分支“foo”还没有合并到master中,它也会包含在内:
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
酒吧食品有驾驭能力的非主人翁
但是,如果我在master上运行相同的命令,则不包含分支“foo”:
git checkout master && git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
酒吧有驾驭能力的非主人翁
这仅仅是因为如果没有另外指定,gitbranch--merged默认为当前分支的HEAD。至少对于我的工作流程来说,我不想删除本地分支,除非它们已合并到主分支,所以我更喜欢使用git-rev-parse的以下变体:
git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
酒吧有驾驭能力的非主人翁
分离的HEAD状态
依赖gitbranch的默认行为--merged在分离HEAD状态下会产生更严重的后果:
git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
酒吧食品脚踏板有驾驭能力的非主人翁
这会删除我刚才打开的分支,“foobar”和“foo”,这几乎肯定不是理想的结果。然而,通过我们修改的命令:
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
酒吧有驾驭能力的非主人翁
一行,包括实际删除
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" | xargs git branch -d
全部打包成一个git别名“sweep”:
git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'
别名接受可选的-f标志。默认行为是只删除已合并到主分支的分支,但-f标志将删除已合并至当前分支的分支。
git sweep
删除了分支条(为9a56952)。删除了分支masterful(为9a56952)。删除了分支notmaster(为9a56952)。
git sweep -f
已删除分支foo(为2cea1ab)。
我使用一个Python脚本,它自动执行最流行的答案中的步骤,并检查其余分支,看看它们是否会在合并时产生任何更改,如果没有,则交互提示删除它们:https://github.com/robertknight/prune-merged-branches.
基于这些答案,我也制作了自己的Bash脚本来实现这一点!
它使用gitbranch--merged和gitbranch-d删除已合并的分支,并在删除之前提示您输入每个分支。
merged_branches () {
local current_branch=$(git rev-parse --abbrev-ref HEAD)
for branch in $(git branch --merged | cut -c3-)
do
echo "Branch $branch is already merged into $current_branch."
echo "Would you like to delete it? [Y]es/[N]o "
read REPLY
if [[ $REPLY =~ ^[Yy] ]]; then
git branch -d $branch
fi
done
}
您可以将提交添加到--merged选项。这样,您可以确保只删除合并到原始/主文件中的分支
以下命令将从原点删除合并的分支。
git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete
您可以测试将删除哪些分支来替换git推送原点--delete with echo
git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo
注意:我对前面的回答不满意,(不在所有系统上工作,不在远程工作,不指定--merged分支,不完全过滤)。所以,我补充了我自己的答案。
主要有两种情况:
地方的
您要删除已合并到另一个本地分支的本地分支。在删除过程中,您希望保留一些重要分支,如master、develop等。
git branch --format "%(refname:short)" --merged master | grep -E -v '^master$|^feature/develop$' | xargs -n 1 git branch -d
笔记:
git分支输出--格式“..”是去除空格并允许精确的grep匹配grep-E用于代替egrep,因此它也适用于没有egrep的系统(即:git for windows)。grep-E-v“^master$|^feature/develd$”是指定我不想删除的本地分支xargs-n 1 git branch-d:执行本地分支的删除(它不适用于远程分支)当然,如果您尝试删除当前签出的分支,会出现错误。所以,我建议提前切换到master。
遥远的
您要删除已合并到另一个远程分支的远程分支。在删除过程中,您希望保留一些重要的分支,如HEAD、master、releases等。
git branch -r --format "%(refname:short)" --merged origin/master | grep -E -v '^*HEAD$|^*/master$|^*release' | cut -d/ -f2- | xargs -n 1 git push --delete origin
笔记:
对于remote,我们使用-r选项并提供完整的分支名称:origin/mastergrep-E-v'^*HEAD$|^*/master$|^*release'是为了匹配我们不想删除的远程分支。cut-d/-f2-:删除不需要的“origin/”前缀,否则将由gitbranch命令打印出来。xargs-n 1 git push--delete origin:执行远程分支的删除。
推荐文章
- 为什么我需要显式地推一个新分支?
- 如何撤消最后的git添加?
- Rubymine:如何让Git忽略Rubymine创建的.idea文件
- Gitignore二进制文件,没有扩展名
- Git隐藏错误:Git隐藏弹出并最终与合并冲突
- 了解Git和GitHub的基础知识
- 没有。Git目录的Git克隆
- Git与Mercurial仓库的互操作性
- 忽略git中修改(但未提交)的文件?
- “git restore”命令是什么?“git restore”和“git reset”之间有什么区别?
- Git合并与强制覆盖
- Git拉另一个分支
- 在Bash命令提示符上添加git分支
- 如何更改Git日志日期格式
- git pull -rebase和git pull -ff-only之间的区别