如何删除所有已合并的 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 origingit delete-merged --doit --local 您也可以使用this app 自动删除合并的分支。 rm -fr work &amp;&amp; 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 有些人的主分支不是主分支,而是developdev,在这种情况下,命令将失败并显示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】:

您需要从这些命令中排除 mastermaindevelop 分支。

本地 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 &amp;&amp; git branch -d `git branch --merged` &amp;&amp; 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

这将删除除masterdevelopment 之外的所有合并分支(合并到主分支)。

【讨论】:

【参考方案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 &lt;(...) &lt;(...) 在括号内给出两个命令的输出差异 grep '&lt;' 过滤存在于第一个列表中但不存在于第二个列表中的分支 cut -c 3- 给出从第三个字符开始的行,因此删除前缀 &lt; xargs git branch -D 对每个分支名称执行 git branch -D

或者,您可以像这样避免grep -v '&lt;'

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()

如果你想排除 ma​​ster 或任何其他分支名称,你可以像这样使用 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)

分支blaissue_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 分支?的主要内容,如果未能解决你的问题,请参考以下文章

从SVN历史列出作者,包括已删除(未合并)的分支

如何删除推送的 git 合并提交

我在 GIT 分支中只有一个提交。如何删除那个提交?

git -- 合并本地多次commit

Git冲突“都已删除”

如何删除git远程分支(转)