ChatGPT解决这个技术问题 Extra ChatGPT

如何删除所有已合并的 Git 分支?

我有很多 Git 分支。如何删除已经合并的分支?有没有一种简单的方法可以将它们全部删除而不是一个一个删除?

稍微更具体一点,git branch -D 删除任何分支,无论它是否已合并。
如果您转到存储库的“分支”部分(例如 github.com/<username>/<repo_name>/branches),您也可以直接从 GitHub 执行此操作。应该有一个所有分支的列表,旁边有一个红色的垃圾桶图标,它将删除选定的分支。比在终端中执行要快得多!还将显示每个分支在 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
rm -fr work && git clone http://example.com/work.git 多年来已成为使用 git 摆脱困境的最简单方法。
最近的问题 How can I delete all git branches which have been “Squash and Merge” via GitHub?,因为在提出此问题时“压缩和合并”不可用。

M
Michael Freidgeim

更新:

如果您的工作流将这些分支作为可能的祖先,您可以添加其他分支以排除,例如 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,这样如果 stdin 为空,它就不会运行 git branch -d。 (根据手册页,这是一个 GNU xargs 扩展)。
O
Oliver

要删除远程上已合并的所有分支:

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
o
oleksii

只是扩展亚当的答案一点:

通过运行 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 和 development 分支
G
Guido Bouman

您需要排除 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
m
mkobit

这也适用于删除除 master 之外的所有合并分支。

git branch --merged | grep -v '^* master$' | grep -v '^  master$' | xargs git branch -d

现在它不会删除任何包含 master 的分支。尝试 grep -v ^master$ 作为中间。
如果您不在 master 上,我也会让 | grep -v '^\*' 避免删除当前分支
这太好了,谢谢!任何人使用它的一个警告:请注意 grep -v '^ master$' 中有两个空格。如果您自己输入并漏掉了一个,如果您不在上面,您将删除 master
@Mr.Polywhirl 你的编辑破坏了命令,你应该恢复它。这两个空格是必需的,因为如果不是当前签出的分支,git branch 将在新行中列出每个分支名称,并在左侧有两个空格。您基本上保证了运行此命令的任何人都会删除他们的主分支,除非它是当前签出的分支。
J
JLRishe

对于那些在 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(叹气,用单引号替换双反引号,我不知道如何格式化包含反引号的文字)
M
Michael Freidgeim

我多年来一直使用亚当的答案。也就是说,在某些情况下它的行为并不像我预期的那样:

包含单词“master”的分支被忽略,例如“notmaster”或“masterful”,而不仅仅是包含单词“dev”的master分支被忽略,例如“dev-test”,而不仅仅是dev分支删除从当前分支的 HEAD 可到达的分支(即不一定是 master)处于分离 HEAD 状态,删除从当前提交可到达的每个分支

1& 2 很容易解决,只需更改正则表达式。 3 取决于您想要的上下文(即仅删除尚未合并到主分支或当前分支的分支)。如果您无意中以分离的 HEAD 状态运行它,则 4 可能会造成灾难性的后果(尽管可以使用 git reflog 恢复)。

最后,我希望这一切都在一个不需要单独的(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

或者:

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

酒吧开发 foo * 高手 高手 非大师

期望的行为:选择所有合并的分支,除了:master、develop 或 current

原来的正则表达式错过了分支“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,如果我重新运行上面的命令来列出我要删除的分支,即使它还没有合并到 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)$)"

酒吧大师

这仅仅是因为 git branch --merged 如果没有另外指定,则默认为当前分支的 HEAD。至少对于我的工作流程,我不想删除本地分支,除非它们已合并到主分支,所以我更喜欢以下变体 using git rev-parse

git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"

酒吧大师

分离的 HEAD 状态

依赖 git branch --merged 的默认行为在分离 HEAD 状态下会产生更严重的后果:

git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"

bar foo foobar 高超的 notmaster

这将删除我刚才所在的分支,“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 标志。默认行为是只删除已合并到 master 的分支,但 -f 标志将删除已合并到当前分支的分支。

git sweep

删除了分支栏(原为 9a56952)。删除了 masterful 分支(原为 9a56952)。删除了分支 notmaster(原为 9a56952)。

git sweep -f

删除了分支 foo(原为 2cea1ab)。


为什么需要创建函数? git config 不是原子的吗?
处理可选的“-f”参数(如果我正确理解您的问题)
但它有什么帮助?我的意思是表达式的开头,!f(){ git branch ...。这是一个函数声明,对吧?为什么不直接从 git branch ... 开始?
你是绝对正确的。相应地编辑了我的答案。谢谢指点!
以下内容与非强制模式不一样吗? git checkout master && git branch -d `git branch --merged` && git checkout - 除了它会删除 develop,但可能是一种更简单的方法。
P
Peter Mortensen

Git Sweep 在这方面做得很好。


现在,这个项目不再维护。请参阅github.com/arc90/git-sweep/pull/43
P
Peter Mortensen

使用 Git 2.5.0 版:

git branch -d `git branch --merged`

这可以删除 master 分支顺便说一句!
真的。我只在确定自己在 master 上时才使用它。
git branch -d $(git branch --merged | grep -v master)
如果您有流程,这很危险,假设您有 master <- stage <- dev。还是最简单的解决方案imo
这会删除当前用户或任何用户合并的所有分支吗?
M
Mariusz Pawelski

如果您使用的是 Windows,则可以使用带有 Out-GridView 的 Windows Powershell 或 Powershell 7 来获得一个不错的分支列表,然后用鼠标选择要删除的分支:

git branch --format "%(refname:short)" --merged  | Out-GridView -PassThru | % { git branch -d $_ }

https://i.stack.imgur.com/78H7G.png


J
Jörn Reimerdes

您可以将提交添加到 --merged 选项。这样,您可以确保只删除合并到的分支,即源/主

以下命令将从您的来源中删除合并的分支。

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete 

您可以测试将删除哪些分支,将 git push origin --delete 替换为 echo

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo

我喜欢测试选项
P
Peter Mortensen

我使用以下 Ruby 脚本来删除我已经合并的本地和远程分支。如果我正在为具有多个遥控器的存储库执行此操作并且只想从一个中删除,我只需在遥控器列表中添加一个 select 语句以仅获取我想要的遥控器。

#!/usr/bin/env ruby

current_branch = `git symbolic-ref --short HEAD`.chomp
if current_branch != "master"
  if $?.exitstatus == 0
    puts "WARNING: You are on branch #{current_branch}, NOT master."
  else
    puts "WARNING: You are not on a branch"
  end
  puts
end

puts "Fetching merged branches..."
remote_branches= `git branch -r --merged`.
  split("\n").
  map(&:strip).
  reject {|b| b =~ /\/(#{current_branch}|master)/}

local_branches= `git branch --merged`.
  gsub(/^\* /, '').
  split("\n").
  map(&:strip).
  reject {|b| b =~ /(#{current_branch}|master)/}

if remote_branches.empty? && local_branches.empty?
  puts "No existing branches have been merged into #{current_branch}."
else
  puts "This will remove the following branches:"
  puts remote_branches.join("\n")
  puts local_branches.join("\n")
  puts "Proceed?"
  if gets =~ /^y/i
    remote_branches.each do |b|
      remote, branch = b.split(/\//)
      `git push #{remote} :#{branch}`
    end

    # Remove local branches
    `git branch -d #{local_branches.join(' ')}`
  else
    puts "No branches removed."
  end
end

介意我为一个小的 git helper 库偷这个花絮吗? github.com/yupiq/git-branch-util
去吧,如果我关心人们以某种方式重用代码,我不会把它放在这里
@mmrobins 您在 remote_branches 行的拒绝语句的开头有一个额外的 \/。这是一个错字还是有目的?
@mmrobins,哦,没关系,我现在看到 b.split(/\//)
如果你想基本上做到这一点,但通过香草 bash 而不是 ruby:stackoverflow.com/a/37999948/430128
C
Community

如何在 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 更高的答案是 stackoverflow.com/questions/6127328/… - 您可以使用该链接重新发布您的评论,然后我会删除它
它还尝试删除 * master :)
V
Viktor Ivliiev

我最喜欢的简单脚本:

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
P
Paras

kuboon 的回答错过了删除分支名称中包含 master 一词的分支。以下改进了他的答案:

git branch -r --merged | grep -v "origin/master$" | sed 's/\s*origin\///' | xargs -n 1 git push --delete origin

当然,它不会删除“master”分支本身:)


p
psuzzi

注意:我对以前的答案不满意,(不是在所有系统上工作,不在远程工作,没有指定 --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、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

笔记:

对于远程,我们使用 -r 选项并提供完整的分支名称:origin/master

grep -E -v '^*HEAD$|^*/master$|^*release' 是为了匹配我们不想删除的远程分支。

cut -d/ -f2- :删除不需要的 'origin/' 前缀,否则由 git branch 命令打印出来。

xargs -n 1 git push --delete origin :执行远程分支的删除。


D
Dan K.K.

如果您将 OhMyZSHgit plugin 一起使用,则可以使用 gbda 别名。


谢谢你!
E
Elmer

我用这个:

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)"
是的,我有时会这样做!将其包含在答案中!
P
Peter Mortensen

Git 中没有命令会自动为您执行此操作。但是您可以编写一个使用 Git 命令的脚本来满足您的需求。这可以通过多种方式完成,具体取决于您使用的分支模型。

如果您需要知道分支是否已合并到 master 中,如果 myTopicBranch 已合并,则以下命令将不产生任何输出(即您可以将其删除)

$ git rev-list master | grep $(git rev-parse myTopicBranch)

您可以使用 Git 分支命令并解析出 Bash 中的所有分支并在所有分支上执行 for 循环。在此循环中,您可以使用上述命令检查是否可以删除分支。


s
styger

git branch --merged | grep -Ev '^(. master|\*)' | xargs -n 1 git branch -d 将删除除当前签出分支和/或 master 之外的所有本地分支。

对于希望了解这些命令的人来说,这是一篇很有帮助的文章:Git Clean: Delete Already Merged Branches, by Steven Harman


t
tusharmakkar08

您可以使用 git-del-br tool

git-del-br -a

您可以使用 pip 安装它

pip install git-del-br

PS:我是该工具的作者。欢迎任何建议/反馈。


@stackoverflow.com/users/100297/martijn-pieters:为什么这个答案被删除和否决?
您的答案和工具不起作用。我花了几个小时在上面。没有什么。
@SpoiledTechie.com:你能告诉我你到底面临什么问题吗?我经常使用它。
如果您想离线使用,我可以分享屏幕截图吗?在那个谷歌邮件的事情上被宠坏了。 :)
P
Peter Mortensen

我使用 git-flow esque 命名方案,所以这对我来说非常安全:

git branch --merged | grep -e "^\s\+\(fix\|feature\)/" | xargs git branch -d

它主要查找以字符串 fix/feature/ 开头的合并提交。


C
Community

在安装了 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
c
chrismendis

如果您想删除所有已合并到您当前所在分支的本地分支,那么我根据之前的答案提出了一个安全命令:

git branch --merged | grep -v \* | grep -v '^\s*master$' | xargs -t -n 1 git branch -d

此命令不会影响您当前的分支或您的主分支。它还会使用 xargs 的 -t 标志在执行此操作之前告诉您它在做什么。


C
Community

Adam's updated answer 的别名版本:

[alias]
    branch-cleanup = "!git branch --merged | egrep -v \"(^\\*|master|dev)\" | xargs git branch -d #"

此外,有关转义复杂别名的便捷提示,请参阅 this answer


H
Heiko Rupp

公认的解决方案非常好,但有一个问题是它还会删除尚未合并到远程的本地分支。

如果您查看输出,您会看到类似

$ 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,因为它在原点有一个遥控器并且不会显示为消失。


c
clovenstone

下面的查询对我有用

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 连接不太好。


H
HK boy

尝试以下命令:

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 查找丢失的提交。


a
alper

根据其中一些答案,我做了my own Bash script to do it too

它使用 git branch --mergedgit branch -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
}

s
sorin

截至2018.07

将此添加到 ~/.gitconfig[alias] 部分:

sweep = !"f() { git branch --merged | egrep -v \"(^\\*|master|dev)\" || true | xargs git branch -d; }; f"

现在您只需调用 git sweep 即可执行所需的清理工作。


对我来说,调用 git sweep 只会列出应该清理的分支,但不会删除它们