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

例子:

分支机构(本地和远程)

主人原始/主起源/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或其他不想/不会编写命令行脚本或不想使用PowerShell的人来说,这是一个更简单的解决方案。

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

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

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

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

其他回答

我在这里找到了答案:如何删除所有已合并的git分支?

git branch --merged | grep -v "\*" | xargs -n 1 git branch -d

确保我们留住主人

您可以通过在第一个grep之后添加另一个grep来确保master或其他分支不会被删除。在这种情况下,您可以:

git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d

因此,如果我们想保持主控、开发和登台,我们会:

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

将此设置为别名

由于它有点长,您可能需要在.zshrc或.bashrc中添加别名。我的别名称为gbpurge(用于git分支清除):

alias gbpurge='git branch --merged | grep -v "\*" | grep -v "master" | grep -v "develop" | grep -v "staging" | xargs -n 1 git branch -d'

然后重新加载.bashrc或.zshrc:

. ~/.bashrc

or

. ~/.zshrc

真正的挑战是当维护者压缩提交时。然后,使用git内置功能(如--merged)的解决方案没有帮助。

gitdelete合并分支工具允许方便地删除分支。我特别喜欢互动模式。

安装(需要python3):

pip install git-delete-merged-branches

然后执行

git-delete-merged-branches --effort=3

--努力=3对于能够删除挤压的分支很重要。

选择

@teppeis/git delete squashed:安装node.js后,执行npx@teppeis/git delete squushed。支持主分支。git delete squashed:未维护:主分支的未命中功能@teppeis/git delete squashed基于此。

这里的答案似乎都不适合我,或者完全按照我的意愿(删除本地分支,而不是远程分支)。所以我写了这篇文章,虽然有点拗口,但很管用。

touch /tmp/remote-refs && touch /tmp/local-refs && touch /tmp/diff-refs;
while shortened=$(git for-each-ref refs/remotes) && echo ${${shortened}//"\/remotes\/origin"} > /tmp/remote-refs &&
shortened=$(git for-each-ref refs/heads | grep -v "master\|develop") && echo ${${shortened}//"\/heads"} > /tmp/local-refs &&
diff=$(comm -13 /tmp/remote-refs /tmp/local-refs) && echo ${${diff}##*refs/} > /tmp/diff-refs &&
xargs git branch -D </tmp/diff-refs; do :; done

只需确保首先运行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

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

grep gone <(git branch -v) | cut -d ' ' -f 3 | xargs git branch -d

上述命令可用于获取在远程中合并和删除的分支,并删除在远程中不再可用的本地分支