删除所有本地git分支

我遵循一个开发stream程,为每个新function或故事卡创build一个新的本地分支。 完成后,我将分支合并到主机中,然后按下。

由于懒惰或健忘的原因,随着时间的推移,往往会发生一大堆地方分支,其中一些(如尖峰)可能没有合并。

我知道如何列出所有本地分支,我知道如何删除一个分支,但我想知道是否有一个git命令,允许我删除所有本地分支?

下面是git branch --merged命令的输出。

 user@machine:~/projects/application[master]$ git branch --merged STORY-123-Short-Description STORY-456-Another-Description STORY-789-Blah-Blah * master 

所有尝试删除使用grep -v \*列出的分支(按照下面的答案)会导致错误:

 error: branch 'STORY-123-Short-Description' not found. error: branch 'STORY-456-Another-Description' not found. error: branch 'STORY-789-Blah-Blah' not found. 

我在用着:
git 1.7.4.1
Ubuntu 10.04
GNU bash,版本4.1.5(1) – 发布
GNU grep 2.5.4

只是一个说明,我会升级到1.7.7 git。 你可能会在这里得到答案,不会在你的版本上工作。 我的猜测是,你必须在分支名称前加refs/heads/

小心,只有在您制作了工作文件夹和.git目录的副本时才继续下面的步骤。

我有时候会直接删除我不想直接从.git/refs/heads删除的分支。 所有这些分支都是包含它们指向的提交的40个字符的sha-1的文本文件。 如果您为其中的任何一个设置了特定的跟踪,那么您的.git/config会包含无关的信息。 您也可以手动删除这些条目。

'git branch -d'子命令可以删除多个分支。 所以,简化@ sblom的答案,但添加一个关键的xargs:

 git branch -D `git branch --merged | grep -v \* | xargs` 

或者进一步简化为:

 git branch --merged | grep -v \* | xargs git branch -D 

重要的是,正如@AndrewC所指出的那样,使用git branch来编写脚本是不鼓励的。 为了避免它使用像这样的东西:

 git for-each-ref --format '%(refname:short)' refs/heads | grep -v master | xargs git branch -D 

谨慎保证删除!

 $ mkdir br $ cd br; git init Initialized empty Git repository in /Users/ebg/test/br/.git/ $ touch README; git add README; git commit -m 'First commit' [master (root-commit) 1d738b5] First commit 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 README $ git branch Story-123-a $ git branch Story-123-b $ git branch Story-123-c $ git branch --merged Story-123-a Story-123-b Story-123-c * master $ git branch --merged | grep -v \* | xargs Story-123-a Story-123-b Story-123-c $ git branch --merged | grep -v \* | xargs git branch -D Deleted branch Story-123-a (was 1d738b5). Deleted branch Story-123-b (was 1d738b5). Deleted branch Story-123-c (was 1d738b5). 

我在github的这个问题上发现了一个更好的方法:

git branch --merged master --no-color | grep -v master | grep -v stable | xargs git branch -d

编辑:添加无色选项,不包括稳定的分支(根据需要添加其他分支)

不build议parsinggit branch的输出,对于堆栈溢出的未来读者不是一个好的答案。

  1. git branch就是所谓的瓷器命令。 瓷器命令不是被devise成机器parsing的,并且输出可以在不同版本的Git之间改变。
  2. 有一些用户configuration选项会改变git branch的输出,使得parsing(例如,着色)变得困难。 如果用户设置了color.branch那么你将在输出中得到控制代码,这将导致error: branch 'foo' not found. 如果你试图将其pipe道到另一个命令。 你可以绕过这个--no-color标志到git branch ,但是谁知道其他的用户configuration可能会破坏一些东西。
  3. git branch可能会做其他烦人分析的事情,比如在当前签出的分支旁边放一个星号

git的维护者对 git branch输出的脚本有这样的说法

为了找出当前分支是什么,偶然/粗心的用户可能会在git分支上编写脚本,这是错误的。 我们主动阻止在脚本中使用包括git分支在内的任何Porcelain命令,因为命令的输出可能会改变以帮助人类消费用例。

build议手动编辑.git目录中的文件(比如.git / refs / heads)的问题同样存在问题(参考.git / packed-refs,或者Git可能在将来改变其内部布局)。

Git提供了for-each-ref命令来检索分支列表。

Git 2.7.X将引入--merged选项,以便您可以执行下面的操作来查找和删除合并到HEAD所有分支

 for mergedBranch in $(git for-each-ref --format '%(refname:short)' --merged HEAD refs/heads/) do git branch -d ${mergedBranch} done 

Git 2.6.X和更旧的版本,你需要列出所有本地分支,然后单独testing它们是否被合并(这会明显慢一些,稍微复杂一点)。

 for branch in $(git for-each-ref --format '%(refname:short)' refs/heads/) do git merge-base --is-ancestor ${branch} HEAD && git branch -d ${branch} done 

要删除除当前已经签出的分支以外的每个分支:

 for b in `git branch --merged | grep -v \*`; do git branch -D $b; done 

我会build议git branch -D $becho $b前几次,以确保它会删除你打算的分支。

删除所有分支,但保留其他“开发”和“主”的简单方法如下:

 git branch | grep -v "develop" | grep -v "master" | xargs git branch -D 

很有用 !

我发现使用文本编辑器和shell更容易。

  1. 在shell中inputgit checkout <TAB> 。 将显示所有本地分支机构。
  2. 将它们复制到文本编辑器,删除那些你需要保留的。
  3. 用空格replace换行符。 (在SublimeText中是非常容易的。)
  4. 打开shell,键入git branch -D <PASTE THE BRANCHES NAMES HERE>

而已。

我有类似的情况,最近发现下面的命令有用。

 git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep>/) printf "%s", $0 }'` 

如果你想保留多个分支,那么

 git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep1>|<Branch_You_Want_to_Keep2>/) printf "%s", $0 }'` 

希望这可以帮助别人。

如果您不需要通过Git本身,也可以手动或以编程方式删除.git / refs /头下的 。 下面应该在Bash下调整最小化:

 shopt -s extglob rm -rf .git/refs/heads/!(master) 

这将删除除主分支之外的所有本地分支。 由于您的上游分支存储在.git / refs / remotes下 ,它们将保持不变。

如果你不使用Bash,或者想要一次递送大量的Git仓库,你可以用GNU find做类似的事情:

 find . \ -path remotes -path logs -prune -o \ -wholename \*.git/refs/heads/\* \! -name master -print0 | xargs -0 rm -rf 

查找解决scheme可能更加便携,但修剪path和文件名是棘手的,可能更容易出错。

没有一个答案完全满足我的需求,所以我们走了:

 git branch --merged | grep -E "(feature|bugfix|hotfix)/" | xargs git branch -D && git remote prune origin 

这将删除合并的所有本地分支,并以feature/bugfix/hotfix/开头。 之后,修剪上游的远程origin (可能需要input密码)。

在Git 1.9.5上工作。

以下脚本删除分支。 使用它并修改它自己的风险等。

根据这个问题的其他答案,我最终为自己写了一个快速的bash脚本。 我把它称为“gitbd”(git branch -D),但是如果你使用它,你可以将它重命名为任何你想要的。

 gitbd() { if [ $# -le 1 ] then local branches_to_delete=`git for-each-ref --format '%(refname:short)' refs/heads/ | grep "$1"` printf "Matching branches:\n\n$branches_to_delete\n\nDelete? [Y/n] " read -n 1 -r # Immediately continue after getting 1 keypress echo # Move to a new line if [[ ! $REPLY == 'N' && ! $REPLY == 'n' ]] then echo $branches_to_delete | xargs git branch -D fi else echo "This command takes one arg (match pattern) or no args (match all)" fi } 

它将提供删除任何与模式参数相匹配的分支,如果传入,或者所有本地分支在没有参数的情况下调用。 这也将给你一个确认的步骤,因为,你知道,我们正在删除的东西,所以这很好。

这有点愚蠢 – 如果没有与模式相匹配的分支,它就没有意识到。

示例输出运行:

 $ gitbd test Matching branches: dummy+test1 dummy+test2 dummy+test3 Delete? [Y/n]