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


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


1320
2018-05-25 15:54


起源


git branch -D删除有分支的分支 不 合并了!小心使用! - Dan Solovay
稍微具体一点 git branch -D 删除任何分支,无论它是否已合并。 - PhilT
您也可以直接从GitHub执行此操作,如果您转到回购的“分支”部分(例如 github.com/<username>/<repo_name>/branches)。应该有一个所有分支的列表,侧面有一个红色垃圾桶图标,将删除所选分支。比在终端上做得快得多!还将显示前进/后退的程度 master每个分支都是。但是,如果运行,本地客户端仍将列出旧分支 git branch -a;使用 git fetch --prune 删除它们(按照 这个答案 )。 - user5359531
脚本在本地或远程执行此操作 - 使用安全检查和预先配置的“安全分支”: github.com/fatso83/dotfiles/tree/master/utils/...  git delete-merged --doit origin 要么 git delete-merged --doit --local - oligofren
你也可以使用 这个程序 自动删除合并的分支。 - Sebass van Boxel


答案:


更新:

如果您的工作流将那些分支作为可能的祖先,您可以添加其他分支以排除master和dev。通常我分支出一个“sprint-start”标签和master,dev和qa不是祖先。

要删除已合并到当前已检出分支的所有本地分支:

git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d

您可以看到master和dev被排除在它们是祖先的情况下。


您可以删除合并的本地分支:

git branch -d branchname

如果没有合并,请使用:

git branch -D branchname

要在旧版本的Git中从远程删除它,请使用:

git push origin :branchname

在更新版本的Git中使用:

git push --delete origin branchname

从远程删除分支后,您可以修剪以删除远程跟踪分支:

git remote prune origin

或者修剪个别远程跟踪分支,正如另一个答案所暗示的那样:

git branch -dr branchname

希望这可以帮助。


2238
2018-05-25 16:40



警告:如果您刚刚创建了一个分支,它也将删除该分支。在运行最顶层命令之前,请确保列表中没有新创建的分支。 - Gary Haran
对应警告:reflog将保存您的培根。所以不要担心。 - Adam Dymitruk
请记住,第一个命令只删除本地分支,因此它不像某些人指出的那样“危险”。 - ifightcrime
PowerShell变种,以便我下次在谷歌搜索答案时能找到它: git branch --merged | %{$_.trim()} | ?{$_ -notmatch 'develop' -and $_ -notmatch 'master'} | %{git branch -d $_} - vorou
这会产生错误 fatal: branch name required 如果你没有应删除的分支。为了避免你可以通过 -r 至 xargs 所以它不会运行 git branch -d 如果标准输入是空的。 (这是一个GNU xargs扩展,根据手册页)。 - Marius Gedminas


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

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

319
2017-08-09 08:45



到目前为止最佳答案。只是一个注释,我的主分支命名 dev 所以我不得不改变它 - Dorian
我不得不补充一下 | grep origin 后 grep -v master 防止推动其他遥控器的分支到原点。强烈推荐使用预先测试输出 git branch -r --merged | grep -v master | grep origin | sed 's/origin\//:/' | xargs -n 1 echo - L0LN1NJ4
我略微修改了以排除 develop 分支也是如此。 git branch -r --merged | grep -v master | grep -v develop | sed 's/origin\///' | xargs -n 1 git push --delete origin。现在这变成了我的别名。 - sarat
是什么让我读到的最佳答案是 -r 这个论点,我在其他任何地方都没有提到过。这是理所当然的,只有当地的分支机构值得做一些家务。但遥控器也充满了垃圾。 - Asbjørn Ulsberg
注意 - 刚刚意识到:这显然会找到合并的分支 目前的分支,不是主人,所以如果你在 myFeatureBranch 它会擦拭 origin/myFeatureBranch。可能是最好的 git checkout master 第一。 - jakub.g


只是简单地扩展了Adam的答案:

通过运行将其添加到您的Git配置中 git config -e --global

[alias]
    cleanup = "!git branch --merged | grep  -v '\\*\\|master\\|develop' | xargs -n 1 git branch -d"

然后你可以删除所有本地合并的分支做一个简单的 git cleanup


136
2018-02-18 15:08



第一个命令不应该是: git branch --merged master 既然你想查看已合并到master中的内容,而不是当前签出的分支? - Joe Phillips
@JoePhilllips有些人的主要分支不是主人而是主人 develop 要么 dev 在这种情况下,命令将失败 fatal: malformed object name 拥有通用命令更好,你有责任运行它 - SKandeel
@SKandeel是的我同意,但大多数人都可以根据具体情况改变这一点。为了清理工作,必须坐在某个分支上有点奇怪 - Joe Phillips
@JoePhilllips这个答案的重点是用有用的git别名打包Adam的答案(这个问题的最佳答案)。亚当的回答没有你的建议,所以很多人发现它很有用所以我倾向于不改变我的想法。如果您对此有强烈的兴趣,我建议您开始讨论亚当的答案 - real_ate
添加 -r 至 xargs 将防止不必要的错误(branch name required)多次运行此别名或没有剩余分支要删除时。我的别名看起来像这样: cleanup = "!git branch --merged | grep -v -P '^\\*|master|develop' | xargs -n1 -r git branch -d" - spezifanta


这也可以删除除master之外的所有合并分支。

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

72
2018-02-07 01:06



现在它不会删除任何分支 master 在里面。尝试 grep -v ^master$ 对于中间。 - wchargin
我也让 | grep -v '^\*' 如果你是的话,避免去掉当前的分支 不是主人 - svassr
这很好,谢谢!使用此功能的任何人都需要注意:请注意,有两个空格 grep -v '^ master$'。如果您自己键入并错过一个,则会删除 master 如果你不在。 - styger
@ Mr.Polywhirl你的编辑打破命令,你应该还原它。这两个空间是必要的,因为 git branch 将列出每个分支名称在新行上,如果它不是当前签出的分支,则左侧有两个空格。您基本上保证运行此命令的任何人都将删除其主分支,除非它是当前签出的分支。 - styger


你想要排除 master & develop 这些命令的分支。

本地git清除:

git branch --merged | grep -v '\*\|master\|develop' | xargs -n 1 git branch -d

远程git清除:

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

同步远程分支的本地注册表:

git fetch -p

57
2017-07-03 16:18



对于远程版本也是+1(但由于我们有远程版本,所以不太需要--prune)。另外值得注意的是,thoose不适用于旧的git版本 - malko
git config --global --add fetch.prune true 在获取或拉取时自动修剪。 - T3rm1
请注意,修剪与远程清除不一样。远程清除实际上删除了与当前分支完全合并的远程分支。 Prune仅清除已删除的远程分支的本地注册表。 - Guido Bouman
完全这个词有点误导,因为一个分支在被合并之前会被认为是合并的,但是在合并之后有一个新的提交,它们没有被合并。 - scones


对于那些在Windows上并且更喜欢PowerShell脚本的人来说,这里是一个删除本地合并分支的人:

function Remove-MergedBranches
{
  git branch --merged |
    ForEach-Object { $_.Trim() } |
    Where-Object {$_ -NotMatch "^\*"} |
    Where-Object {-not ( $_ -Like "*master" )} |
    ForEach-Object { git branch -d $_ }
}

32
2018-06-10 14:00



出于好奇的缘故,这可以缩短为 git branch --merged | ?{-not ($_ -like "*master")} | %{git branch -d $_.trim()} - Iain Ballard
@IainBallard当然,我可以使用别名。当您想要最大化可读性时,不建议这样做。 github.com/darkoperator/PSStyleGuide/blob/master/English.md - Klas Mellbourn
当然。我发现你的答案非常有用:-)但是有时长形式的powershell语法会阻碍块中发生的事情。但主要是,我提出了一些你可以复制/粘贴或输入一次性的东西。再次感谢。 - Iain Ballard
@IainBallard欢迎你:) - Klas Mellbourn
这是Windows cmd shell的单行程序,用于保留master和当前分支: for /f "usebackq" %B in (``git branch --merged^|findstr /v /c:"* " /c:"master"``) do @git branch -d %B (叹气,用单个替换双反引号,我不知道如何格式化包含反引号的文字) - yoyo


Git Sweep 做得很好。


19
2018-02-04 13:53





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

以下命令将从您的原点删除合并的分支。

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

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

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

13
2017-07-08 06:28



我喜欢测试选项 - iwein


我使用以下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

11
2017-09-27 23:41



介意我是否会为一个小小的git helper库窃取这个花絮? github.com/yupiq/git-branch-util - logan
去吧,如果我关心人们以某种​​方式重用代码,我就不会把它放在这里 - mmrobins
@mmrobins你有一个额外的 \/ 在拒绝声明的开头 remote_branches 线。这是一个错字还是有用? - Jawwad
@mmrobins,哦,别介意我看到了 b.split(/\//) 现在排队 - Jawwad
如果你想基本上这样做,但通过vanilla bash而不是ruby: stackoverflow.com/a/37999948/430128 - Raman


使用Git版本2.5.0:

git branch -d `git branch --merged`

11
2017-09-14 16:20



这可以删除 master 分支顺便说一句! - Islam Wazery
真正。我只在确定自己开的时候才使用它 master。 - drautb
git branch -d $(git branch --merged | grep -v master) - alexg


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

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

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


8
2017-10-04 06:05