博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何删除所有已合并的Git分支?
阅读量:3574 次
发布时间:2019-05-20

本文共 13796 字,大约阅读时间需要 45 分钟。

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


#1楼

我使用以下Ruby脚本删除我已经合并的本地和远程分支。 如果我要对具有多个远程服务器的存储库执行此操作,而只想从其中删除,则只需将select语句添加到远程服务器列表中,即可获取所需的远程服务器。

#!/usr/bin/env rubycurrent_branch = `git symbolic-ref --short HEAD`.chompif 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  putsendputs "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."  endend

#2楼

在这方面做得很好。


#3楼

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

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

#4楼

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

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

UPDATE(@oliver;由于不适合注释,但已经有足够的答案了) :如果您在分支ABC上,则ABC将出现在git branch -r --merged的结果中,因为未指定分支,所以分支默认到当前分支,并且分支始终符合合并到其自身的资格(因为分支与自身之间没有区别!)。

因此,要么指定分支:

git branch -r --merged master | grep -v master ...

或第一个结帐管理员:

git checkout master | git branch -r --merged | grep -v ...

#5楼

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

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

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


#6楼

基于这些答案,我也制作 !

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

#7楼

为了避免从master以外的任何其他分支意外运行命令,我使用以下bash脚本。 否则,运行git branch --merged | grep -v "\\*" | xargs -n 1 git branch -d git branch --merged | grep -v "\\*" | xargs -n 1 git branch -d git branch --merged | grep -v "\\*" | xargs -n 1 git branch -d来自已经关闭了master的分支,可以删除master分支。

#!/bin/bashbranch_name="$(git symbolic-ref HEAD 2>/dev/null)" ||branch_name="(unnamed branch)"     # detached HEADbranch_name=${branch_name##refs/heads/}if [[ $branch_name == 'master' ]]; then   read -r -p "Are you sure? [y/N] " response   if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then       git branch --merged | grep -v "\*" | xargs -n 1 git branch -d   fielse   echo "Refusing to delete branches that are not merged into '$branch_name'. Checkout master first."fi

#8楼

如果您想删除已经合并到当前所在分支中的所有本地分支,那么基于较早的答案,我想出了一个安全的命令来执行此操作:

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

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


#9楼

只是扩大了亚当的答案:

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

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

然后,您可以执行简单的git cleanup删除所有本地合并分支。


#10楼

对于那些使用Windows并喜欢PowerShell脚本的用户,以下是一种删除本地合并分支的方法:

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

#11楼

您将要从这些命令中排除masterdevelop分支。

本地git clear:

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

#12楼

您可以将提交添加到--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

#13楼

要删除已合并到主分支的本地分支,我使用以下别名( git config -e --global ):

cleanup = "!git branch --merged master | grep -v '^*\\|master' | xargs -n 1 git branch -D"

我正在使用git branch -D来避免error: The branch 'some-branch' is not fully merged. 我当前的结帐与master分支不同时显示的消息。


#14楼

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

对于那些希望了解这些命令的人来说,这是一篇有用的文章: 。


#15楼

如何在PowerShell控制台中删除合并的分支

git branch --merged | %{git branch -d $_.Trim()}

如果要排除master或任何其他分支名称,则可以使用PowerShell这样的PowerShell Select-String进行管道传递,并将结果传递给git branch -d

git branch -d $(git branch --merged | Select-String -NotMatch "master" | %{$_.ToString().Trim()})

#16楼

使用Git 2.5.0版本:

git branch -d `git branch --merged`

#17楼

您可以使用git-del-br

git-del-br -a

您可以使用以下方式通过pip安装它

pip install git-del-br

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


#18楼

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

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

基本上,它查找以字符串fix/feature/开头的合并提交。


#19楼

别名版本:

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

另外,请参阅以获取有关转义复杂别名的便捷提示。


#20楼

尝试以下命令:

git branch -d $(git branch --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

通过使用git rev-parse将获得以将其排除。 如果收到错误,则意味着没有要删除的本地分支。

要对远程分支执行相同操作(使用您的远程名称更改origin ),请尝试:

git push origin -vd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD) | cut -d/ -f2)

如果您有多个遥控器,请添加grep origin |cut前仅过滤origin

如果以上命令失败,请尝试首先删除合并的远程跟踪分支:

git branch -rd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

然后git fetch再次git fetch远程,并再次使用前面的git push -vd命令。

如果您经常使用它,请考虑将其作为别名添加到~/.gitconfig文件中。

如果您错误地删除了一些分支,请使用git reflog查找丢失的提交。


#21楼

编写一个脚本,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 $branchnewdonegit checkout masterfor 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 $branchnewdone

#22楼

下面的查询对我有用

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连接则效果不佳。


#23楼

在安装了 Windows上,egrep -v将不起作用

git branch --merged | grep -E -v "(master|test|dev)" | xargs git branch -d

其中grep -E -v等效于egrep -v

使用-d删除已合并的分支,或-D删除未合并的分支


#24楼

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

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

$ 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操作,因为它起源远方,并且不会消失。


#25楼

截至2018.07

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

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

现在,您可以调用git sweep来执行所需的清理。


#26楼

$ git config --global alias.cleanup'!git branch --merged origin/master | egrep -v "(^\*|master|staging|dev)" | xargs git branch -d'

(分成多行以提高可读性)

调用“ git cleanup”将删除已经合并到原始服务器/主服务器中的本地分支。 它跳过了master,staging和dev,因为在正常情况下我们不想删除它们。

分解一下,这就是它的作用:

  1. git config --global alias.cleanup
    • 这将创建一个名为“ cleanup”的全局别名(跨所有存储库)
  2. ! 该命令开头的意思是我们将使用一些非git命令作为此别名的一部分,因此我们需要在此处实际运行bash命令
  3. git branch --merged origin/master
    • 此命令返回已经合并到origin/master中的分支名称的列表
  4. egrep -v "(^\\*|master|staging|dev)"
    • 这将从已合并的分支列表中删除master,staging和dev分支。 我们不想删除这些分支,因为它们不是功能。
  5. xargs git branch -d
    • 这将为每个未合并的分支运行git branch -d xxxxx命令。 这将一一删除本地分支。

#27楼

我已经使用亚当的答案多年了。 就是说,在某些情况下,它的行为不符合我的预期:

  1. 包含单词“ master”的分支被忽略,例如“ notmaster”或“ masterful”,而不仅仅是master分支
  2. 包含单词“ dev”的分支将被忽略,例如“ dev-test”,而不仅仅是dev分支
  3. 删除当前分支的HEAD可以访问的分支(即不一定是主节点)
  4. 在分离的HEAD状态下,从当前提交中删除每个可到达的分支

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

最后,我希望所有这些都在一个单一的代码中,不需要单独的(Bash | Ruby | Python)脚本。

TL; DR

创建一个git别名“ sweep”,它接受可选的-f标志:

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 repo

mkdir sweep-test && cd sweep-test && git initecho "hello" > hellogit add . && git commit -am "initial commit"

创建一些新分支

git branch foo && git branch bar && git branch develop && git branch notmaster && git branch masterfulgit branch --list
bar develop foo * master masterful notmaster

期望的行为:选择所有合并的分支,除了:母版,开发版或当前版

原始正则表达式会错过分支“ masterful”和“ notmaster”:

git checkout foogit branch --merged | egrep -v "(^\*|master|dev)"
bar

使用更新的正则表达式(现在不包括“开发”而不是“开发”):

git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar masterful notmaster

切换到分支foo,进行新的提交,然后基于foo签出新的分支foobar:

echo "foo" > foogit add . && git commit -am "foo"git checkout -b foobarecho "foobar" > foobargit 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分支,否则我不希望删除它们,因此我更喜欢以下变体:

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

分离的HEAD状态

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

git checkout foobargit checkout HEAD~0git 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).

#28楼

对于Windows,您可以使用以下命令安装并删除所有远程分支:

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

#29楼

如果您使用的是Windows,则可以将Windows Powershell与一起 (遗憾的是,现在Powershell Core中已经没有了),以提供一个不错的分支列表,并用鼠标选择要删除的分支:

git branch --merged | Out-GridView -PassThru | % { git branch -d $_.Trim() }

单击确定后,Powershell会将此分支名称传递给git branch -d命令并删除它们


#30楼

对我来说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- git branch -r | grep -v HEAD | cut -d/ -f2-给出远程分支的列表,过滤出HEAD
  • diff <(...) <(...)给出括号内两个命令输出的差异
  • grep '<'过滤第一个列表中存在但第二个列表中不存在的分支
  • cut -c 3-给出从第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

#31楼

更新:

如果您的工作流程可能将其作为祖先,则可以添加其他分支以排除像master和dev这样的分支。 通常,我从“ sprint-start”标签分支出来,而master,dev和qa不是祖先。

首先,列出所有在远程中合并的分支。

git branch --merged

您可能会看到几个不想删除的分支。 我们可以添加一些参数来跳过不想删除的重要分支,例如master或developer。 以下命令将跳过master分支以及其中包含dev的所有内容。

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

如果要跳过,可以将其添加到egrep命令中,如下所示。 分支skip_branch_name不会被删除。

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

删除所有已经合并到当前签出分支中的本地分支:

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

希望这可以帮助。


#32楼

Git中没有命令可以自动为您执行此操作。 但是您可以编写一个使用Git命令的脚本,以提供所需的内容。 根据您使用的分支模型,可以通过多种方式完成此操作。

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

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

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

转载地址:http://zeogj.baihongyu.com/

你可能感兴趣的文章
小甲鱼Python第十三讲(戴上了枷锁的列表)
查看>>
小甲鱼Python第十四讲(各种奇葩的内置方法)
查看>>
小甲鱼Python第十五讲(格式化)
查看>>
小甲鱼Python第十七讲(Python的乐高积木)
查看>>
小甲鱼Python第十九讲(函数,我的地盘听我的)
查看>>
小甲鱼python第二十讲(内嵌函数和闭包)
查看>>
小甲鱼Python第二十一讲(lambda表达式)
查看>>
小甲鱼Python第二十三讲、第二十四讲(递归-这帮小兔崽子、汉诺塔)
查看>>
小甲鱼Python第二十七讲(集合)
查看>>
可调谐半导体激光器的窄线宽测试及压缩
查看>>
matlab中 %d,%f,%c,%s
查看>>
常见的光纤接头汇总
查看>>
半导体激光器—问题整理(二)
查看>>
科研日记7.31
查看>>
zemax仿真二向色镜
查看>>
stm32单片机编程时extern的用法
查看>>
UART4和5的问题
查看>>
Spring框架中在并发访问时的线程安全性
查看>>
网站部署
查看>>
什么情况下会发生栈内存溢出。
查看>>