是否有一种简单的方法可以删除所有远程对等分支不再存在的跟踪分支?

例子:

分支机构(本地和远程)

主人原始/主起源/bug-fix-a起源/bug-fix-b起源/bug-fix-c

在本地,我只有一个主分支。现在我需要处理bug-fix-a,所以我检查它,处理它,并将更改推到远程。接下来,我对bug-fix-b做同样的操作。

分支机构(本地和远程)

主人bug-fix-abug-fix-b型原始/主起源/bug-fix-a起源/bug-fix-b起源/bug-fix-c

现在我有本地分支机构master,bug-fix-a,bug--fix-b。主分支维护者将把我的更改合并到主分支中,并删除他已经合并的所有分支。

因此,当前状态为:

分支机构(本地和远程)

主人bug-fix-abug-fix-b型原始/主起源/bug-fix-c

现在我想调用一些命令来删除分支(在本例中为bug-fix-a、bug-fix-b),这些分支在远程存储库中不再表示。

它类似于现有命令git remote prune origin,但更类似于git local prune origin。


当前回答

Windows解决方案

对于Microsoft Windows Powershell:

git结帐主机;git远程更新原点--prune;git branch-vv|选择字符串-模式“:gone]”|%{$_.toString().Trim().Split(“”)[0]}|%{git branch-d$_}

解释

git checkout master切换到master分支

git远程更新原点--修剪远程分支

gitbranch-vv获取所有分支的详细输出(git引用)

选择String-Pattern“:gone]”仅获取从远程删除的记录。

%{$_.toString().Trim().Split(“”)[0]}获取分支名称

%{gitbranch-d$_}删除分支

其他回答

如果您使用安装了Oh My zsh的zsh shell,那么最简单的安全方法就是使用内置的自动完成。

首先确定要删除的分支:

~ git branch --merged

  branch1
  branch2
  branch3
* master

这将显示已合并分支的列表

在您知道一些要删除的内容后,请键入:

~ git branch -d 

您只需点击[tab],就会显示一个本地分支的列表。使用tab complete或只需再次单击[tab],您就可以使用[enter]在它们之间循环选择分支。

选项卡反复选择分支,直到您拥有要删除的分支列表:

~ git branch -d branch1 branch2 branch3

现在只需按enter键即可删除分支集合。

如果您在终端上没有使用zsh。。。拿到这里。

因为有些答案不能防止意外删除

git fetch-p&&LANG=c git branch-vv|awk'/:gone]/&&/^\*/{print$1}‘|xargs git branch-d

过滤掉第一列中有*的分支是很重要的。

我发现基于Powershell的解决方案比这里的许多实现更清晰。

# prune deleted remoted branches
git fetch -p

# get all branches and their corresponding remote status
# deleted remotes will be marked [gone]
git branch -v |
  #find ones marked [gone], capture branchName
  select-string -Pattern '^  (?<branchName>\S+)\s+\w+ \[gone\]' | 
  foreach-object{ 
     #delete the captured branchname.
     git branch -D $_.Matches[0].Groups['branchName']
  }

我认为没有内置命令来执行此操作,但可以安全地执行以下操作:

git checkout master
git branch -d bug-fix-a

当您使用-d时,git将拒绝删除分支,除非它完全合并到HEAD或其上游远程跟踪分支中。因此,您可以始终循环每个ref的git输出,并尝试删除每个分支。这种方法的问题是,我怀疑您可能不希望因为origin/bug-fix-d包含其历史而删除bug--fix-d。相反,您可以创建如下脚本:

#!/bin/sh

git checkout master &&
for r in $(git for-each-ref refs/heads --format='%(refname:short)')
do
  if [ x$(git merge-base master "$r") = x$(git rev-parse --verify "$r") ]
  then
    if [ "$r" != "master" ]
    then
      git branch -d "$r"
    fi
  fi
done

警告:我尚未测试此脚本-请小心使用。。。

这将删除本地不存在的所有远程分支(在ruby中):

bs = `git branch`.split; bs2 = `git branch -r | grep origin`.split.reject { |b| bs.include?(b.split('/')[1..-1].join('/')) }; bs2.each { |b| puts `git  push origin --delete #{b.split('/')[1..-1].join('/')}` }

解释:

# local branches
bs = `git branch`.split
# remote branches
bs2 = `git branch -r | grep origin`.split
# reject the branches that are present locally (removes origin/ in front)
bs2.reject! { |b| bs.include?(b.split('/')[1..-1].join('/')) }
# deletes the branches (removes origin/ in front)
bs2.each { |b| puts `git  push origin --delete #{b.split('/')[1..-1].join('/')}` }