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

例子:

分支机构(本地和远程)

主人原始/主起源/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。


当前回答

你可以这样做:

git branch -vv | grep 'origin/.*: gone]' | awk '{print $1}' | xargs git branch -d

附笔。:正如Sam H。

首先执行以下操作:

git remote prune origin

其他回答

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

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

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

对于Windows或其他不想/不会编写命令行脚本或不想使用PowerShell的人来说,这是一个更简单的解决方案。

将分支列表转储到文件中gitbranch>branches.txt(或git branch--merged>branches.txt,如果您是腰带和吊带类型;gitbranch-d将防止删除未合并的分支)

在编辑器中打开该文件并合并所有行(我使用了升华文本,所以突出显示所有行并按ctrl+j)

在分支列表前面添加gitbranch-d。

全选、复制并粘贴(在windows cmd窗口中单击鼠标右键)到命令行中。

也许这个命令就是你想要的。

运行后:

git remote prune origin

然后运行:

diff <(git branch | sed -e 's/*/ /g') <(git branch -r | sed -e 's/origin\///g') | grep '^<'

这将显示所有不在(gitbranch-r)而是在(git branch)中的分支

此方法有一个问题,它还将在本地显示以前未推送的分支

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

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

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

最安全的方法是对每个ref使用带有插值变量%(upstream:track)的“管道”命令git,当分支不再位于远程时,该变量将消失:

git fetch -p && for branch in $(git for-each-ref --format '%(refname) %(upstream:track)' refs/heads | awk '$2 == "[gone]" {sub("refs/heads/", "", $1); print $1}'); do git branch -D $branch; done

这种方法比使用“瓷”命令更安全,因为不会有意外匹配提交消息部分的风险。下面是一个使用“瓷”git命令的版本:

git fetch -p && for branch in $(git branch -vv | grep ': gone]' | awk '{print $1}'); do git branch -D $branch; done

这种工作方式是在命令之后

git fetch -p

运行时删除远程引用

git branch -vv

它将显示“已离开”作为远程状态。例如

$ git branch -vv
  master                 b900de9 [origin/master: behind 4] Fixed bug
  release/v3.8           fdd2f4e [origin/release/v3.8: behind 2] Fixed bug
  release/v3.9           0d680d0 [origin/release/v3.9: behind 2] Updated comments
  bug/1234               57379e4 [origin/bug/1234: gone] Fixed bug

这是脚本迭代的内容。