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

例子:

分支机构(本地和远程)

主人原始/主起源/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 remote prune origin

然后运行:

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

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

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

其他回答

另一个答案,大量借鉴Patrick的答案(我喜欢这个答案,因为它似乎消除了任何关于去哪儿的歧义),将在git分支输出中匹配),但添加了*nix弯曲。

最简单的形式是:

git branch --list --format \
  "%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)" \
  | xargs git branch -D

我的路径上有一个git-gone脚本:

#!/usr/bin/env bash

action() {
  ${DELETE} && xargs git branch -D || cat
}

get_gone() {
  git branch --list --format \
    "%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)"
}

main() {
  DELETE=false
  while [ $# -gt 0 ] ; do
    case "${1}" in
      (-[dD] | --delete) DELETE=true ;;
    esac
    shift
  done
  get_gone | action
}

main "${@}"

注:--format选项似乎很新;我需要将git从2.10.something升级到2.16.3才能获得它。

编辑:修改为包含参考名的建议:来自Benjamin W。

NB2-我只在bash中进行了测试,因此有了hashbang,但可能可以移植到sh。

看来每个人都有解决办法。好吧,如果你喜欢一个带有TUI(基于文本的用户界面)的交互式工具,我写了一个叫做gitxcleaner的工具。它可以找到合并的分支、重新基础的分支(使用相同的提交消息提交)、修剪的分支或手动选择的分支。

https://github.com/lzap/git-xcleaner

删除已合并到主控形状中的所有分支,但不要尝试删除主控形状本身:

git checkout master&&git pull origin master&&git fetch-p&&git branch-d$(git branch--merged|grep master-v)

或添加别名:

alias gitcleanlocal=“git checkout master&&git pull origin master&&git fetch-p&&git branch-d$(git branch--merged|grep master-v)”

说明:

git结帐主结帐主分支

git pull-origin master确保本地分支合并了所有远程更改

gitfetch-p删除对已删除的远程分支的引用

gitbranch-d$(gitbranch-master--merged|grepmaster-v)删除已合并到master中的所有分支,但不要尝试删除master本身

真正的挑战是当维护者压缩提交时。然后,使用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基于此。

最安全的方法是对每个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

这是脚本迭代的内容。