如何删除所有已合并的 Git 分支?
Posted
技术标签:
【中文标题】如何删除所有已合并的 Git 分支?【英文标题】:How can I delete all Git branches which have been merged? 【发布时间】:2011-09-01 21:49:41 【问题描述】:我有很多 Git 分支。如何删除已经合并的分支?有没有一种简单的方法可以将它们全部删除而不是一个一个删除?
【问题讨论】:
更具体一点,git branch -D
删除任何分支,无论它是否已合并。
您也可以直接从 GitHub 执行此操作,如果您转到存储库的“分支”部分(例如 github.com/<username>/<repo_name>/branches)。应该有一个所有分支的列表,旁边有一个红色的垃圾桶图标,它将删除选定的分支。比在终端中执行要快得多!还将显示每个分支的领先/落后master
。但是,如果您运行git branch -a
,您的本地客户端仍会列出旧分支;使用 git fetch --prune
删除它们(根据 this answer )。
在本地或远程执行此操作的脚本 - 带有安全检查和预配置的“安全分支”:github.com/fatso83/dotfiles/tree/master/utils/…git delete-merged --doit origin
或 git delete-merged --doit --local
您也可以使用this app 自动删除合并的分支。
rm -fr work && git clone http://example.com/work.git
多年来已成为用 git 摆脱困境的最简单方法。
【参考方案1】:
稍微扩展一下亚当的回答:
通过运行 git config -e --global
将其添加到您的 Git 配置中
[alias]
cleanup = "!git branch --merged | grep -v '\\*\\|master\\|develop' | xargs -n 1 -r git branch -d"
然后你可以通过简单的git cleanup
删除所有本地合并的分支。
【讨论】:
第一个命令不应该是:git branch --merged master
,因为您想查看已合并到 master 中的内容,当前未签出分支?
@JoePhilllips 有些人的主分支不是主分支,而是develop
或dev
,在这种情况下,命令将失败并显示fatal: malformed object name
,最好有一个通用命令,你有负责运行它
@JoePhilllips 这个答案的重点是将亚当的答案(这个问题的最佳答案)打包成有用的 git 别名。亚当的回答没有你的建议,很多人发现这很有用,所以我倾向于不改变我的。如果您对此有强烈的感觉,我建议您开始讨论亚当的答案
将 -r
添加到 xargs
将防止在多次运行此别名或没有要删除的分支时出现不必要的错误 (branch name required
)。我的别名如下所示:cleanup = "!git branch --merged | grep -v -P '^\\*|master|develop' | xargs -n1 -r git branch -d"
当前命令没有过滤掉master和develop分支【参考方案2】:
我最喜欢的简单脚本:
git branch --merged | grep -E -v "(master|develop|other)" | xargs git branch -d
【讨论】:
删除除了选中的git branch | grep -E -v "(master|develop|other)" | xargs git branch -D
【参考方案3】:
我用这个:
git branch --delete $(git branch --format '%(refname:short)' --merged | grep --invert-match 'main\|master\|branch-to-skip')
它以指定格式列出所有合并的分支,然后将该列表提供给 git branch --delete。
【讨论】:
这是一个严重低估的答案。将这种方法与最佳答案的冗长结合起来,它就是赢家: git branch --merged| egrep -v "(^*|master|main|dev|skip_branch_name)" 是的,我有时会这样做!将其包含在答案中!【参考方案4】:对于那些使用 Windows 并喜欢 PowerShell 脚本的人,这里有一个删除本地合并分支的脚本:
function Remove-MergedBranches
git branch --merged |
ForEach-Object $_.Trim() |
Where-Object $_ -NotMatch "^\*" |
Where-Object -not ( $_ -Like "*master" or $_ -Like "*main") |
ForEach-Object git branch -d $_
或短版:
git branch --merged | %$_.trim() | ?$_ -notmatch 'dev' -and $_ -notmatch 'master' -and $_ -notmatch 'main' | %git branch -d $_.trim()
【讨论】:
为了好奇,这可以缩短为git branch --merged | ?-not ($_ -like "*master") | %git branch -d $_.trim()
@IainBallard 当然,我可以使用别名。当您想最大限度地提高可读性时,不建议这样做。 github.com/darkoperator/PSStyleGuide/blob/master/English.md
当然。我发现您的回答非常有帮助 :-) 但是,有时长格式的 powershell 语法会妨碍块中发生的事情。但主要是,我提出了一些您可以一次性复制/粘贴或键入的内容。再次感谢。
这是一个用于 Windows cmd shell 的单行代码,它保留了 master 和您当前的分支:for /f "usebackq" %B in (``git branch --merged^|findstr /v /c:"* " /c:"master"``) do @git branch -d %B
(叹气,将双反引号替换为单引号,我不确定如何格式化包含反引号)【参考方案5】:
git cleanup
脚本来自git-toolbelt
删除所有已经合并到 master 或 开发。保持其他分支躺在周围。将是最保守的删除。
删除本地和远程源中的分支。
【讨论】:
【参考方案6】:您需要从这些命令中排除 master
、main
和 develop
分支。
本地 git 清除:
git branch --merged | grep -v '\*\|master\|main\|develop' | xargs -n 1 git branch -d
远程 git 清除:
git branch -r --merged | grep -v '\*\|master\|main\|develop' | sed 's/origin\///' | xargs -n 1 git push --delete origin
同步远程分支的本地注册表:
git fetch -p
【讨论】:
+1 也适用于远程版本(但由于我们有远程 --prune,所以不需要)。还值得注意的是,这些不适用于较旧的 git 版本git config --global --add fetch.prune true
在获取或拉取时自动修剪。
请注意,修剪与远程清除不同。远程清除实际上删除了与您当前分支完全合并的远程分支。 Prune 只会清理已删除的远程分支的本地注册表。
完全这个词有点误导,因为一个分支在之前被合并时会被认为是合并的,但是在合并之后有新的提交,这些提交没有被合并。
要在一次调用中删除所有原始遥控器,我使用了这个:git branch -r --merged | grep -v '\*\|master\|develop' | grep '^\s*origin/' | sed 's/origin\///' | tr "\n" " " | xargs git push --delete origin
【参考方案7】:
更新:
如果您的工作流程将它们作为可能的祖先,您可以添加其他分支以排除,例如 master 和 dev。通常我从“sprint-start”标签分支出来,master、dev 和 qa 不是祖先。
首先,列出在远程合并的本地跟踪分支(您可以考虑使用 -r 标志列出所有远程跟踪分支,如其他答案中所建议的那样)。
git branch --merged
您可能会看到一些您不想删除的分支。我们可以添加一些参数来跳过我们不想删除的重要分支,例如 master 或 develop。以下命令将跳过 master 分支以及其中包含 dev 的任何内容。
git branch --merged| egrep -v "(^\*|master|main|dev)"
如果你想跳过,你可以将它添加到 egrep 命令中,如下所示。不会删除分支skip_branch_name
。
git branch --merged| egrep -v "(^\*|master|main|dev|skip_branch_name)"
删除所有已合并到当前签出分支的本地分支:
git branch --merged | egrep -v "(^\*|master|main|dev)" | xargs git branch -d
您可以看到 master 和 dev 被排除在外,以防它们是祖先。
您可以删除合并的本地分支:
git branch -d branchname
如果未合并,请使用:
git branch -D branchname
从远程使用中删除它:
git push --delete origin branchname
git push origin :branchname # for really old git
从远程删除分支后,您可以通过以下方式修剪以摆脱远程跟踪分支:
git remote prune origin
或修剪个别远程跟踪分支,正如另一个答案所暗示的那样:
git branch -dr branchname
【讨论】:
警告:如果您刚刚创建了一个分支,它也会删除该分支。在运行最上面的命令之前,确保列表中没有新创建的分支。 警告相反:reflog 会保存你的培根。所以不用担心。 请记住,第一个命令只删除本地分支,因此它不像某些人指出的那样“危险”。 PowerShell 变体,以便下次我搜索答案时可以在这里找到它:git branch --merged | %$_.trim() | ?$_ -notmatch 'develop' -and $_ -notmatch 'master' | %git branch -d $_
如果您没有应删除的分支,则会产生错误fatal: branch name required
。为避免这种情况,您可以将-r
传递给xargs
,这样如果标准输入为空,它就不会运行git branch -d
。 (根据手册页,这是一个 GNU xargs 扩展)。【参考方案8】:
我多年来一直使用亚当的答案。也就是说,在某些情况下它的行为并不符合我的预期:
-
包含单词“master”的分支被忽略,例如“notmaster”或“masterful”,而不仅仅是 master 分支
包含单词“dev”的分支被忽略,例如“dev-test”,而不仅仅是 dev 分支
删除从当前分支(即不一定是master)的HEAD可以到达的分支
处于分离 HEAD 状态,删除当前提交中可到达的每个分支
1 和 2 很容易解决,只需更改正则表达式。
3 取决于您想要的上下文(即仅删除尚未合并到 master 或当前分支的分支)。
如果您无意中在分离的 HEAD 状态下运行它,则 4 可能会造成灾难性的后果(尽管可以使用 git reflog
恢复)。
最后,我希望这一切都在一个不需要单独的 (Bash|Ruby|Python) 脚本的单行程序中。
TL;DR
创建一个接受可选 -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
或:
git sweep -f
长而详细的答案
对我来说,创建一个带有一些分支和提交以测试正确行为的示例 git repo 是最简单的:
使用单个提交创建一个新的 git 存储库
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
bar develop foo * master masterful notmaster
期望的行为:选择所有合并的分支,除了:master、develop 或 current
原来的正则表达式遗漏了分支“masterful”和“notmaster”:
git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"
bar
使用更新的正则表达式(现在不包括“develop”而不是“dev”):
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar masterful notmaster
切换到分支 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,如果我重新运行上面的命令来列出我要删除的分支,即使没有合并到 master 中,分支“foo”也会被包含:
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar foo masterful notmaster
但是,如果我在 master 上运行相同的命令,则不包括分支“foo”:
git checkout master && git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar masterful notmaster
这仅仅是因为git branch --merged
如果没有另外指定,默认为当前分支的 HEAD。至少对于我的工作流程,我不想删除本地分支,除非它们已合并到 master,所以我更喜欢以下变体 using git rev-parse:
git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
bar masterful notmaster
分离的 HEAD 状态
依赖git branch --merged
的默认行为在分离的 HEAD 状态下会产生更严重的后果:
git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar foo foobar masterful notmaster
这会删除我刚才所在的分支,“foobar”和“foo”,这几乎肯定不是预期的结果。 但是,使用我们修改后的命令:
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
bar masterful notmaster
一行,包括实际删除
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
标志。默认行为是只删除已经合并到master的分支,但是-f
标志会删除已经合并到当前分支的分支。
git sweep
Deleted branch bar (was 9a56952). Deleted branch masterful (was 9a56952). Deleted branch notmaster (was 9a56952).
git sweep -f
Deleted branch foo (was 2cea1ab).
【讨论】:
为什么需要创建函数?git config
不是原子的吗?
处理可选的'-f'参数(如果我理解你的问题的话)
但是它有什么帮助呢?我的意思是表达式的开头,!f() git branch ...
。这是一个函数声明,对吧?为什么不直接以git branch ...
开头?
你说得对。相应地编辑了我的答案。谢谢指点!
下面会不会和非强制模式一样? git checkout master && git branch -d `git branch --merged` && git checkout -
除了会删除 develop
,但可能是更简单的方法。【参考方案9】:
要删除合并的分支,git-delete-merged-branches 比 shell hack 更健壮、更方便。它还检测 rebase 合并和 squash 合并。它的自述文件有more details。
【讨论】:
【参考方案10】:我发现的最简单的方法是只删除本地分支,而不是远程分支:
$ git branch --merged | grep -v master | xargs -n 1 git branch -D
此命令将仅删除已合并到您的主分支中的分支。如果您不想删除其他分支,请小心,例如 staging
。
【讨论】:
如果你使用zsh,你可以输入gbda
来应用这个命令【参考方案11】:
试试下面的命令:
git branch -d $(git branch --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))
通过使用git rev-parse
将得到the current branch name 以排除它。如果您收到错误消息,则表示没有要删除的本地分支。
要对远程分支执行相同操作(将 origin
更改为您的远程名称),请尝试:
git push origin -vd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD) | cut -d/ -f2)
如果您有多个遥控器,请在cut
之前添加grep origin |
以仅过滤origin
。
如果上述命令失败,请先尝试删除合并的远程跟踪分支:
git branch -rd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))
然后再次git fetch
遥控器并再次使用之前的git push -vd
命令。
如果您经常使用它,请考虑将别名添加到您的 ~/.gitconfig
文件中。
如果您错误地删除了某些分支,请使用 git reflog
查找丢失的提交。
【讨论】:
【参考方案12】:如果您使用的是 HubFlow 或 GitFlow 等分支模型,您可以使用此命令删除合并的功能分支:
git branch --merged | grep feature.* | grep -v "\*" | xargs -n 1 git branch -d
【讨论】:
【参考方案13】:刚刚为此创建了 python 脚本:
import sys
from shutil import which
import logging
from subprocess import check_output, call
logger = logging.getLogger(__name__)
if __name__ == '__main__':
if which("git") is None:
logger.error("git is not found!")
sys.exit(-1)
branches = check_output("git branch -r --merged".split()).strip().decode("utf8").splitlines()
current = check_output("git branch --show-current".split()).strip().decode("utf8")
blacklist = ["master", current]
for b in branches:
b = b.split("/")[-1]
if b in blacklist:
continue
else:
if input(f"Do you want to delete branch: 'b' [y/n]\n").lower() == "y":
call(f"git branch -D b".split())
call(f"git push --delete origin b".split())
【讨论】:
【参考方案14】:如果您使用的是 Windows,您可以使用带有 Out-GridView 的 Windows Powershell 或 Powershell 7 来获得一个不错的分支列表,然后用鼠标选择要删除的分支:
git branch --format "%(refname:short)" --merged | Out-GridView -PassThru | % git branch -d $_
单击确定后,Powershell 会将此分支名称传递给git branch -d
命令并删除它们
【讨论】:
【参考方案15】:我一直在使用以下方法在一个 cmd 中删除合并的本地和远程分支。
我的bashrc
文件中有以下内容:
function rmb
current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
if [ "$current_branch" != "master" ]; then
echo "WARNING: You are on branch $current_branch, NOT master."
fi
echo "Fetching merged branches..."
git remote prune origin
remote_branches=$(git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$")
local_branches=$(git branch --merged | grep -v 'master$' | grep -v "$current_branch$")
if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
echo "No existing branches have been merged into $current_branch."
else
echo "This will remove the following branches:"
if [ -n "$remote_branches" ]; then
echo "$remote_branches"
fi
if [ -n "$local_branches" ]; then
echo "$local_branches"
fi
read -p "Continue? (y/n): " -n 1 choice
echo
if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
# Remove remote branches
git push origin `git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$" | sed 's/origin\//:/g' | tr -d '\n'`
# Remove local branches
git branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/origin\///g' | tr -d '\n'`
else
echo "No branches removed."
fi
fi
原创source
这不会删除主分支,而是删除合并的本地和远程分支。一旦你在你的 rc 文件中有了这个,只需运行rmb
,你就会看到一个合并分支的列表,这些分支将被清理并要求确认操作。您也可以将代码修改为不要求确认,但最好保留它。
【讨论】:
【参考方案16】:如果您将OhMyZSH 与git plugin 一起使用,则可以使用gbda
别名。
【讨论】:
谢谢!【参考方案17】:注意:我对以前的答案不满意,(不适用于所有系统,不适用于远程,未指定 --merged 分支,未精确过滤)。所以,我添加我自己的答案。
主要有两种情况:
本地
您想要删除已合并到另一个本地分支的本地分支。在删除过程中,你想保留一些重要的分支,比如master、develop等。
git branch --format "%(refname:short)" --merged master | grep -E -v '^master$|^feature/develop$' | xargs -n 1 git branch -d
注意事项:
git branch output --format
".." 是去除空格并允许精确的 grep 匹配
grep -E
用于而不是 egrep
,因此它也适用于没有 egrep 的系统(即:用于 windows 的 git)。
grep -E -v '^master$|^feature/develop$'
是指定我不想删除的本地分支
xargs -n 1 git branch -d
:执行本地分支的删除(远程分支不行)
当然如果您尝试删除当前签出的分支,则会收到错误消息。所以,我建议提前切换到master。
远程
您想要删除已合并到另一个远程分支的远程分支。。在删除过程中,您希望保留一些重要的分支,例如 HEAD、master、release 等。
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
注意事项:
对于远程,我们使用-r
选项并提供完整的分支名称:origin/master
grep -E -v '^*HEAD$|^*/master$|^*release'
是匹配我们不想删除的远程分支。
cut -d/ -f2-
:删除不需要的 'origin/' 前缀,否则会由 git branch
命令打印出来。
xargs -n 1 git push --delete origin
: 删除远程分支。
【讨论】:
【参考方案18】:如果您想删除合并的分支,您只需删除远程跟踪分支,除非您另有说明。
所以要删除这些分支,你可以这样做
git branch --remote --merged origin/master | egrep -v "(^\*|master|development)" | cut -b 10- | xargs git push --delete origin
这将删除除master
和development
之外的所有合并分支(合并到主分支)。
【讨论】:
【参考方案19】:删除远程上所有已合并的分支:
git branch -r --merged | grep -v master | sed 's/origin\//:/' | xargs -n 1 git push origin
在最新版本的 Git 中
git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin
更新(@oliver;因为不适合评论,但已经有足够的答案):如果您在分支 ABC 上,那么 ABC 将出现在 git branch -r --merged
的结果中,因为分支是未指定,因此分支默认为当前分支,并且分支始终符合合并到自身的条件(因为分支与自身之间没有区别!)。
所以要么指定分支:
git branch -r --merged master | grep -v master ...
或第一个结帐大师:
git checkout master | git branch -r --merged | grep -v ...
【讨论】:
迄今为止最好的答案。请注意,我的主分支名为dev
,所以我不得不更改它
我必须在grep -v master
之后添加| grep origin
以防止将其他遥控器的分支推送到原点。强烈建议预先测试输出,使用git branch -r --merged | grep -v master | grep origin | sed 's/origin\//:/' | xargs -n 1 echo
我稍作修改以排除 develop
分支。 git branch -r --merged | grep -v master | grep -v develop | sed 's/origin\///' | xargs -n 1 git push --delete origin
。现在这竟然是我的别名。
这是我读过的最佳答案的原因是 -r
论点,我在其他任何地方都没有提到过。人们理所当然地认为,只有当地的分支机构才值得做一些家务。但是遥控器也充满了垃圾。
警告 - 刚刚意识到:这显然会发现分支合并到 当前分支,而不是主分支,所以如果你在 myFeatureBranch
上,它将擦除 origin/myFeatureBranch
。可能最好先git checkout master
。【参考方案20】:
对我来说,git branch --merged
不显示通过 GitHub PR 合并的分支。我不确定原因,但我使用以下行删除所有没有远程跟踪分支的本地分支:
diff <(git branch --format "%(refname:short)") <(git branch -r | grep -v HEAD | cut -d/ -f2-) | grep '<' | cut -c 3- | xargs git branch -D
说明:
git branch --format "%(refname:short)"
给出了当地分支机构的列表
git branch -r | grep -v HEAD | cut -d/ -f2-
给出远程分支列表,过滤掉HEAD
diff <(...) <(...)
在括号内给出两个命令的输出差异
grep '<'
过滤存在于第一个列表中但不存在于第二个列表中的分支
cut -c 3-
给出从第三个字符开始的行,因此删除前缀 <
xargs git branch -D
对每个分支名称执行 git branch -D
或者,您可以像这样避免grep -v '<'
:
diff --old-line-format="%L" --new-line-format="" --unchanged-line-format="" <(git branch --format "%(refname:short)") <(git branch -r | grep -v HEAD | cut -d/ -f2-) | xargs git branch -D
【讨论】:
【参考方案21】:git-delete-merged-branches
来自git-extras
回购。
https://github.com/tj/git-extras/blob/master/Commands.md#git-delete-merged-branches
【讨论】:
【参考方案22】:如何在 PowerShell 控制台中删除合并的分支
git branch --merged | %git branch -d $_.Trim()
如果你想排除 master 或任何其他分支名称,你可以像这样使用 PowerShell Select-String 管道并将结果传递给git branch -d
:
git branch -d $(git branch --merged | Select-String -NotMatch "master" | %$_.ToString().Trim())
【讨论】:
更高的答案建议过滤主分支或其他分支。对于那些希望在 powershell 中执行此操作的人: git branch --merged | findstr /v "master" | %git 分支 -d $_.trim() @tredzko 好点。 FTR 更高的答案是 ***.com/questions/6127328/… - 您可以使用该链接重新发布您的评论,然后我会删除此 它还试图删除* master
:)【参考方案23】:
对于 Windows,您可以使用以下命令安装 Cygwin 并删除所有远程分支:
git branch -r --merged | "C:\cygwin64\bin\grep.exe" -v master | "C:\cygwin64\bin\sed.exe" 's/origin\///' | "C:\cygwin64\bin\xargs.exe" -n 1 git push --delete origin
【讨论】:
【参考方案24】:在安装了git bash 的 Windows 上 egrep -v 将不起作用
git branch --merged | grep -E -v "(master|test|dev)" | xargs git branch -d
其中grep -E -v
等同于egrep -v
使用-d
删除已经合并的分支或
-D
删除 未合并 分支
【讨论】:
egrep -v 对我有用。我正在使用 gitextensions 安装程序中的 gitbash【参考方案25】:$ git config --global alias.cleanup
'!git branch --merged origin/master | egrep -v "(^\*|master|staging|dev)" | xargs git branch -d'
(为了便于阅读,分成多行)
调用“git cleanup”将删除已经合并到origin/master的本地分支。它会跳过 master、staging 和 dev,因为我们不想在正常情况下删除它们。
打破这个,这就是它正在做的事情:
git config --global alias.cleanup
这将创建一个名为“cleanup”的全局别名(在您的所有存储库中)
命令开头的 !
表示我们将使用一些非 git 命令作为此别名的一部分,因此我们需要在此处实际运行 bash 命令
git branch --merged origin/master
该命令返回已经合并到origin/master
中的分支名称列表
egrep -v "(^\*|master|staging|dev)"
这将从已合并的分支列表中删除主分支、暂存分支和开发分支。我们不想删除这些分支,因为它们不是功能。
xargs git branch -d
这将为每个未合并的分支运行git branch -d xxxxx
命令。这会一一删除本地分支。
【讨论】:
【参考方案26】:截至 2018.07
将此添加到您的~/.gitconfig
的[alias]
部分:
sweep = !"f() git branch --merged | egrep -v \"(^\\*|master|dev)\" || true | xargs git branch -d; ; f"
现在您只需致电 git sweep
即可执行所需的清理工作。
【讨论】:
对我来说,调用 git sweep 只会列出应该清理的分支,但不会删除它们【参考方案27】:公认的解决方案非常好,但有一个问题是它还会删除尚未合并到远程的本地分支。
如果你查看输出,你会看到类似
$ git branch --merged master -v
api_doc 3a05427 [gone] Start of describing the Java API
bla 52e080a Update wording.
branch-1.0 32f1a72 [maven-release-plugin] prepare release 1.0.1
initial_proposal 6e59fb0 [gone] Original proposal, converted to AsciiDoc.
issue_248 be2ba3c Skip unit-for-type checking. This needs more work. (#254)
master be2ba3c Skip unit-for-type checking. This needs more work. (#254)
分支bla
和issue_248
是本地分支,会被静默删除。
但是你也可以看到[gone]
这个词,它表示已经推送到远程的分支(现在已经消失了),因此表示可以删除分支。
因此可以将原始答案更改为(拆分为多行以缩短行长)
git branch --merged master -v | \
grep "\\[gone\\]" | \
sed -e 's/^..//' -e 's/\S* .*//' | \
xargs git branch -d
保护尚未合并的分支。 也不需要主人保护它的 grepping,因为它在原点有一个远程并且不会显示为消失。
【讨论】:
【参考方案28】:以下查询对我有用
for branch in `git branch -r --merged | grep -v '\*\|master\|develop'|awk 'NR > 0 print$1'|awk 'gsub(/origin\//, "")1'`;do git push origin --delete $branch; done
这将过滤 grep 管道中的任何给定分支。
在 http 克隆上运行良好,但对 ssh 连接不太好。
【讨论】:
【参考方案29】:编写一个脚本,让 Git 检出所有已合并到 master 的分支。
然后做git checkout master
。
最后,删除合并的分支。
for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do
branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///")
echo branch-name: $branchnew
git checkout $branchnew
done
git checkout master
for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do
branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///")
echo branch-name: $branchnew
git push origin --delete $branchnew
done
【讨论】:
【参考方案30】:我使用 git-flow esque 命名方案,所以这对我来说非常安全:
git branch --merged | grep -e "^\s\+\(fix\|feature\)/" | xargs git branch -d
它基本上会查找以字符串 fix/
或 feature/
开头的合并提交。
【讨论】:
以上是关于如何删除所有已合并的 Git 分支?的主要内容,如果未能解决你的问题,请参考以下文章