如何删除所有已合并的 Git 分支?
如何删除已经合并的分支?我可以一次性删除它们,而不是逐一删除每个分支吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如何删除已经合并的分支?我可以一次性删除它们,而不是逐一删除每个分支吗?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(30)
注意:如果您的工作流程将这些分支作为可能的祖先,您可以添加其他分支来排除,例如 master 和 dev。通常我会从“sprint-start”标签中分支出来,master、dev 和 qa 不是祖先。
首先,列出在远程合并的本地跟踪分支(考虑使用 -r 标志列出所有远程跟踪分支)。
您可能会看到一些不想删除的分支。我们可以添加一些参数来跳过我们不想删除的重要分支,例如master或develop。以下命令将跳过 master 分支以及其中包含 dev 的任何分支。
第一部分 (
^\*|^+
) 排除当前分支和在另一个工作树中检出的任何分支。如果想跳过,可以将其添加到egrep命令中,如下所示。分支
skip_branch_name
将不会被删除。要删除已合并到当前签出分支的所有本地分支:
您可以看到 master 和 dev 被排除,以防它们是祖先。
您可以使用以下方法删除合并的本地分支:
如果未合并,请使用:
要从远程删除它,请使用: 从远程
删除分支后,您可以使用以下方法修剪以摆脱远程跟踪分支:
或修剪单个远程跟踪正如另一个答案所暗示的那样,分支具有:
NOTE: You can add other branches to exclude like master and dev if your workflow has those as a possible ancestor. Usually I branch off of a "sprint-start" tag and master, dev and qa are not ancestors.
First, list locally-tracking branches that were merged in remote (consider using
-r
flag to list all remote-tracking branches).You might see few branches you don't want to remove. We can add few arguments to skip important branches that we don't want to delete like master or a develop. The following command will skip master branch and anything that has dev in it.
The first part (
^\*|^+
) exclude the current branch and any branch checked out in another worktree.If you want to skip, you can add it to the egrep command like the following. The branch
skip_branch_name
will not be deleted.To delete all local branches that are already merged into the currently checked out branch:
You can see that master and dev are excluded in case they are an ancestor.
You can delete a merged local branch with:
If it's not merged, use:
To delete it from the remote use:
Once you delete the branch from the remote, you can prune to get rid of remote tracking branches with:
or prune individual remote tracking branches, as the other answer suggests, with:
要删除远程上已合并的所有分支:
在最新版本的 Git
UPDATE (by @oliver; 因为不适合评论,但已经有足够的答案):如果您在分支 ABC 上,则ABC 将出现在 gitbranch -r --merged 的结果中,因为未指定分支,因此分支默认为当前分支,并且分支始终符合合并到自身的条件(因为没有差异)分支与其自身之间!)。
因此,要么指定分支:
要么首先结账主控:
To delete all branches on remote that are already merged:
In more recent versions of Git
UPDATE (by @oliver; since does not fit in comment, but enough answers already): if you are on branch ABC then ABC will appear in the results of
git branch -r --merged
because the branch is not specified, so branch defaults to current branch, and a branch always qualifies as merged to itself (because there are no differences between a branch and itself!).So either specify the branch:
OR first checkout master:
只需稍微扩展 Adam 的答案:
通过运行 git config -e --global 将其添加到您的 Git 配置中
,然后您可以删除所有本地合并分支,执行简单的 git cleanup代码>.
Just extending Adam's answer a little bit:
Add this to your Git configuration by running
git config -e --global
And then you can delete all the local merged branches doing a simple
git cleanup
.您需要排除
master
、main
和master
。从这些命令中开发分支。本地git清除:
远程git清除:
同步远程分支的本地注册表:
You'll want to exclude the
master
,main
&develop
branches from those commands.Local git clear:
Remote git clear:
Sync local registry of remote branches:
这也适用于删除除 master 之外的所有合并分支。
编辑:也忽略主分支,因为它现在正在使用
This also works to delete all merged branches except master.
Edit: Also ignoring main branch as it's being used these days
对于那些使用 Windows 并且更喜欢 PowerShell 脚本的人来说,这里有一个删除本地合并分支的脚本:
或者简短的版本:
For those of you that are on Windows and prefer PowerShell scripts, here is one that deletes local merged branches:
Or the short version:
我已经使用亚当的答案很多年了。也就是说,在某些情况下它的行为并不符合我的预期:
1 和 1 中可到达的每个分支。 2 很容易解决,只需更改正则表达式即可。
3 取决于您想要的上下文(即仅删除尚未合并到 master 或针对当前分支的分支)。
如果您无意中在分离的 HEAD 状态下运行此版本,则 4 可能会造成灾难性的后果(尽管可以使用 git reflog 恢复)。
最后,我希望这一切都在一行中,不需要单独的 (Bash|Ruby|Python) 脚本。
TL;DR
创建一个 git 别名“sweep”,它接受可选的
-f
标志:并使用以下命令调用它:
或:
长而详细的答案
对我来说,创建一个示例 git 存储库是最简单的分支和提交来测试正确的行为:
使用单个提交创建一个新的 git 存储库
创建一些新分支
期望的行为:选择所有合并的分支,除了: master、develop 或 current
原始正则表达式缺少分支“masterful”和“notmaster”:
使用更新的正则表达式(现在排除“develop”而不是“dev”):
切换到分支 foo,进行新的提交,然后基于 foo 检出一个新分支 foobar:
我当前的分支是 foobar,如果我重新运行上面的命令来列出我要删除的分支,则分支“foo " 即使尚未合并到 master 中,也已包含在内:
但是,如果我在 master 上运行相同的命令,则不包含分支“foo”:
这只是因为如果没有另外指定, gitbranch --merged 默认为当前分支的 HEAD。至少对于我的工作流程,我不想删除本地分支,除非它们已合并到主分支,所以我更喜欢以下变体 使用 git rev-parse:
分离的 HEAD 状态
依赖 gitbranch --merged 的默认行为在分离的 HEAD 状态下会产生更严重的后果:
这会删除我刚刚所在的分支“foobar”和“foo”,这几乎肯定不是期望的结果。
然而,使用我们修改后的命令:
一行,包括实际的删除
全部包装到一个 git 别名“sweep”中:
该别名接受一个可选的
-f
标志。默认行为是仅删除已合并到 master 的分支,但-f
标志将删除已合并到当前分支的分支。I've used Adam's answer for years now. That said, that there are some cases where it wasn't behaving as I expected:
1 & 2 were straightforward to address, with just a change to the regex.
3 depends on the context of what you want (i.e. only delete branches that haven't been merged into master or against your current branch).
4 has the potential to be disastrous (although recoverable with
git reflog
), if you unintentionally ran this in detached HEAD state.Finally, I wanted this to all be in a one-liner that didn't require a separate (Bash|Ruby|Python) script.
TL;DR
Create a git alias "sweep" that accepts an optional
-f
flag:and invoke it with:
or:
The long, detailed answer
It was easiest for me to create an example git repo with some branches and commits to test the correct behavior:
Create a new git repo with a single commit
Create some new branches
Desired behavior: select all merged branches except: master, develop or current
The original regex misses the branches "masterful" and "notmaster" :
With the updated regex (which now excludes "develop" rather than "dev"):
Switch to branch foo, make a new commit, then checkout a new branch, foobar, based on foo:
My current branch is foobar, and if I re-run the above command to list the branches I want to delete, the branch "foo" is included even though it hasn't been merged into master:
However, if I run the same command on master, the branch "foo" is not included:
And this is simply because
git branch --merged
defaults to the HEAD of the current branch if not otherwise specified. At least for my workflow, I don't want to delete local branches unless they've been merged to master, so I prefer the following variant using git rev-parse:Detached HEAD state
Relying on the default behavior of
git branch --merged
has even more significant consequences in detached HEAD state:This would have deleted the branch I was just on, "foobar" along with "foo", which is almost certainly not the desired outcome.
With our revised command, however:
One line, including the actual delete
All wrapped up into a git alias "sweep":
The alias accepts an optional
-f
flag. The default behavior is to only delete branches that have been merged into master, but the-f
flag will delete branches that have been merged into the current branch.这里有很多不好的答案。这可能是您想要的:
这会选择已合并到
master
中的所有本地分支(包括master
)、和 非后代分支master
(不包括master
本身)。--format
是必需的,因为默认情况下 Git 会为当前签出的分支打印星号。您也可以使用 git for-each-ref 来完成此操作,但它似乎更复杂(它也列出了远程分支)。您不想要:
gitbranch--merged
(没有master
):这将列出已“合并”到您的< em>当前已签出提交(即HEAD
),这可能是意外的并且不是您想要的。--no-contains
。gitbranch --delete
可以删除多个分支。更新:我已经使用这个有一段时间了,效果很好。有两个小缺陷:
如果没有要删除的分支,则会出现错误。在我看来,这对于交互式使用来说很好。无论如何,您都不应该在脚本中使用它,因为它是 Bash,并且 Bash 不应该用于脚本编写。
它不会删除指向与
master
相同提交的分支。我有一个工具,它可以自动对我的所有分支进行变基,对于已合并的分支,它可以将它们保留在其中这种状态。这对你来说可能并不重要。So many bad answers here. This is what you probably want:
This selects all local branches that have been merged into
master
(includingmaster
), and that aren't descendent ofmaster
(which excludesmaster
itself). The--format
is necessary because by default Git prints asterisks for the currently checked out branches. You might be able to do this withgit for-each-ref
too but it seems more complicated (it lists remote branches too).You don't want:
git branch --merged
(withoutmaster
): This will list branches that have been "merged" into your currently checked out commit (i.e.HEAD
), which is probably unexpected and not what you want.| grep -v master
: There's no need for this; you can just use--no-contains
.| xargs
: Again, no need.git branch --delete
can delete more than one branch.Update: I've been using this for a while and it works pretty well. There are two minor flaws:
If there are no branches to delete it will give you an error. That's fine for interactive use IMO. You shouldn't be using this in a script anyway since it's Bash and Bash should not be used for scripting.
It won't delete branches that point to the same commit as
master
. I have a tool that automatically rebases all my branches, and for ones that have been merged it can leave them in this state. This may not matter to you.使用 Git 版本 2.5.0:
Using Git version 2.5.0:
如果您使用的是 Windows,则可以通过 Out-GridView 以获得一个不错的分支列表,并用鼠标选择要删除的分支:
单击“确定”后,Powershell 会将此分支名称传递给 gitbranch -d 命令并删除它们
If you're on Windows you can use Windows Powershell or Powershell 7 with Out-GridView to have a nice list of branches and select with mouse which one you want to delete:
after clicking OK Powershell will pass this branches names to
git branch -d
command and delete them您可以将提交添加到 --merged 选项。
这样,您可以确保仅删除合并到即 origin/master 的分支
。以下命令将从您的源中删除合并的分支。
您可以测试将删除哪些分支,将 git push origin --delete 替换为 echo
You can add the commit to the --merged option.
This way you can make sure only to remove branches which are merged into i.e. the origin/master
Following command will remove merged branches from your origin.
You can test which branches will be removed replacing the git push origin --delete with echo
我最喜欢的简单脚本:
My favorite and simple script:
如何在 PowerShell 控制台中删除合并的分支
如果您想排除 master 或任何其他分支名称,您可以像这样使用 PowerShell Select-String 进行管道传输,并将结果传递给 gitbranch -d< /代码>:
How to delete merged branches in PowerShell console
If you want to exclude master or any other branch names, you can pipe with PowerShell Select-String like this and pass the result to
git branch -d
:我使用以下 Ruby 脚本来删除已合并的本地和远程分支。如果我正在为具有多个遥控器的存储库执行此操作,并且只想从其中删除一个,我只需向遥控器列表添加一条 select 语句即可仅获取我想要的遥控器。
I use the following Ruby script to delete my already merged local and remote branches. If I'm doing it for a repository with multiple remotes and only want to delete from one, I just add a select statement to the remotes list to only get the remotes I want.
注意:我对以前的答案不满意(不适用于所有系统,不适用于远程,未指定 --merged 分支,未精确过滤)。所以,我添加我自己的答案。
主要有两种情况:
本地
您想要删除已合并到另一个本地分支的本地分支。在删除过程中,你想保留一些重要的分支,如master、develop等。
注意:
gitbranchoutput--format
“..”是去掉空格,允许精确的 grep 匹配grep -E
使用而不是egrep
,因此它也可以在没有egrep 的系统中工作(即:Windows 的 git)。grep -E -v '^master$|^feature/develop$'
是指定我不想删除的本地分支xargs -n 1 gitbranch -d
>:执行本地分支的删除(这对远程分支不起作用)远程
您想要删除已合并到另一个远程分支的远程分支。在删除过程中,您希望保留一些重要的分支,例如 HEAD、master、releases 等。
注意:
-r
选项并提供 < em>完整分支名称:origin/master
grep -E -v '^*HEAD$|^*/master$|^*release'
是匹配我们不想删除的远程分支。cut -d/ -f2-
:删除不需要的 'origin/' 前缀,否则该前缀将由 gitbranch 命令打印出来。xargs -n 1 git push --delete origin
:执行删除远程分支。Note: I am not happy with previous answers, (not working on all systems, not working on remote, not specifying the --merged branch, not filtering exactly). So, I add my own answer.
There are two main cases:
Local
You want to delete local branches that are already merged to another local branch. During the deletion, you want to keep some important branches, like master, develop, etc.
Notes:
git branch output --format
".." is to strip whitespaces and allow exact grep matchinggrep -E
is used instead ofegrep
, so it works also in systems without egrep (i.e.: git for windows).grep -E -v '^master$|^feature/develop$'
is to specify local branches that I don't want to deletexargs -n 1 git branch -d
: perform the deletion of local branches (it won't work for remote ones)Remote
You want to delete remote branches that are already merged to another remote branch. During the deletion, you want to keep some important branches, like HEAD, master, releases, etc.
Notes:
-r
option and provide the full branch name:origin/master
grep -E -v '^*HEAD$|^*/master$|^*release'
is to match the remote branches that we don't want to delete.cut -d/ -f2-
: remove the unneeded 'origin/' prefix that otherwise is printed out by thegit branch
command.xargs -n 1 git push --delete origin
: perform the deletion of remote branches.如果您将 OhMyZSH 与 gbda 别名“https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/git” rel="noreferrer">git 插件。
You can use
gbda
alias if you're using OhMyZSH with git plugin.我使用这个:
它以指定的格式列出所有合并的分支,然后将该列表提供给 gitbranch --delete。
I use this:
It lists all merged branched in the specified format, then it feeds that list to git branch --delete.
kuboon 的答案错过了删除分支名称中包含 master 一词的分支。
以下改进了他的答案:
当然,它不会删除“master”分支本身:)
kuboon's answer missed deleting branches which have the word master in the branch name.
The following improves on his answer:
Of course, it does not delete the "master" branch itself :)
Git 中没有任何命令可以自动为您执行此操作。但是您可以编写一个使用 Git 命令的脚本来满足您的需要。这可以通过多种方式完成,具体取决于您使用的分支模型。
如果您需要知道分支是否已合并到 master 中,如果 myTopicBranch 已合并(即您可以删除它),以下命令将不会产生任何输出
您可以使用 Git 分支命令并解析 Bash 中的所有分支并执行 < code>for 循环所有分支。在此循环中,您使用上述命令检查是否可以删除分支。
There is no command in Git that will do this for you automatically. But you can write a script that uses Git commands to give you what you need. This could be done in many ways depending on what branching model you are using.
If you need to know if a branch has been merged into master the following command will yield no output if myTopicBranch has been merged (i.e. you can delete it)
You could use the Git branch command and parse out all branches in Bash and do a
for
loop over all branches. In this loop you check with above command if you can delete the branch or not.git 分支 --merged | grep -Ev '^(.master|\*)' | xargs -n 1 gitbranch -d 将删除除当前签出分支和/或
master
之外的所有本地分支。对于那些希望了解这些命令的人来说,这是一篇有用的文章: Git Clean:删除已合并的分支,作者:史蒂文·哈曼。
git branch --merged | grep -Ev '^(. master|\*)' | xargs -n 1 git branch -d
will delete all local branches except the current checked out branch and/ormaster
.Here's a helpful article for those looking to understand these commands: Git Clean: Delete Already Merged Branches, by Steven Harman.
您可以使用
git-del-br
工具。您可以使用
pip
安装它P.S:我是该工具的作者。欢迎任何建议/反馈。
You can use
git-del-br
tool.You can install it via
pip
usingP.S: I am the author of the tool. Any suggestions/feedback are welcome.
我使用 git-flow esque 命名方案,因此这对我来说非常安全:
它基本上查找以字符串
fix/
或feature/
开头的合并提交。I use a git-flow esque naming scheme, so this works very safely for me:
It basically looks for merged commits that start with either string
fix/
orfeature/
.接受的解决方案非常好,但有一个问题,它还会删除尚未合并到远程的本地分支。
如果您查看输出,您会看到类似
Branches
bla
和issue_248
的内容是本地分支,它们将被静默删除。但您还可以看到单词
[gone]
,它表示已推送到远程的分支(现已消失),因此表示可以删除分支。因此,原始答案可以更改为(拆分为多行以缩短行长度)
以保护尚未合并的分支。
此外,不需要对 master 进行 grep 保护以保护它,因为它在原点有一个遥控器,并且不会显示为已消失。
The accepted solution is pretty good, but has the one issue that it also deletes local branches that were not yet merged into a remote.
If you look at the output of you will see something like
Branches
bla
andissue_248
are local branches that would be deleted silently.But you can also see the word
[gone]
, which indicate branches that had been pushed to a remote (which is now gone) and thus denote branches can be deleted.The original answer can thus be changed to (split into multiline for shorter line length)
to protect the not yet merged branches.
Also the grepping for master to protect it, is not needed, as this has a remote at origin and does not show up as gone.
在安装了 git bash 的 Windows 上
egrep -v
将无法使用grep - E -v
相当于egrep -v
使用
-d
删除已经合并的分支或-D
删除未合并分支On Windows with git bash installed
egrep -v
will not workwhere
grep -E -v
is equivalent ofegrep -v
Use
-d
to remove already merged branches or-D
to remove unmerged branches如果您想删除已合并到您当前所在分支的所有本地分支,那么根据之前的答案,我想出了一个安全的命令来执行此操作:
此命令不会影响您当前的分支分支或您的主分支。它还会使用 xargs 的 -t 标志在执行操作之前告诉您它正在做什么。
If you'd like to delete all local branches that are already merged in to the branch that you are currently on, then I've come up with a safe command to do so, based on earlier answers:
This command will not affect your current branch or your master branch. It will also tell you what it's doing before it does it, using the -t flag of xargs.
Adam 的更新答案的别名版本:
另请参阅这个答案提供了有关转义复杂别名的便捷提示。
Alias version of Adam's updated answer:
Also, see this answer for handy tips on escaping complex aliases.
下面的查询对我有用
,这将过滤 grep 管道中的任何给定分支。
在 http 克隆上效果很好,但在 ssh 连接上效果不太好。
Below query works for me
and this will filter any given branch in the grep pipe.
Works well over http clone, but not so well for the ssh connection.
基于其中一些答案,我制作了我自己的 Bash 脚本来执行此操作!
它使用 gitbranch --merged 和 gitbranch -d 删除已合并的分支,并在删除之前提示您输入每个分支。
Based on some of these answers I made my own Bash script to do it too!
It uses
git branch --merged
andgit branch -d
to delete the branches that have been merged and prompts you for each of the branches before deleting.尝试以下命令:
通过使用
git rev-parse
将按顺序获取当前分支名称排除它。如果出现错误,则意味着没有要删除的本地分支。要对远程分支执行相同的操作(将
origin
更改为您的远程名称),请尝试:如果您有多个远程分支,请在
之前添加
仅过滤grep origin |
>cutorigin
。如果上述命令失败,请尝试先删除合并的远程跟踪分支:
然后
git fetch
再次远程并再次使用之前的 git push -vd 命令。如果您经常使用它,请考虑将其作为别名添加到您的
~/.gitconfig
文件中。如果您错误地删除了一些分支,请使用 git reflog 来查找丢失的提交。
Try the following command:
By using
git rev-parse
will get the current branch name in order to exclude it. If you got the error, that means there are no local branches to remove.To do the same with remote branches (change
origin
with your remote name), try:In case you've multiple remotes, add
grep origin |
beforecut
to filter only theorigin
.If above command fails, try to delete the merged remote-tracking branches first:
Then
git fetch
the remote again and use the previousgit push -vd
command again.If you're using it often, consider adding as aliases into your
~/.gitconfig
file.In case you've removed some branches by mistake, use
git reflog
to find the lost commits.从 2018.07 开始,
将其添加到
~/.gitconfig
的[alias]
部分:现在您只需调用
git swing
即可执行所需的清理。As of 2018.07
Add this to
[alias]
section of your~/.gitconfig
:Now you can just call
git sweep
to perform that needed cleanup.