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

例子:

分支机构(本地和远程)

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


当前回答

这里有一个解决方法,我用它来处理鱼壳。在Mac OS X 10.11.5、fish 2.3.0和git 2.8.3上测试。

function git_clean_branches
  set base_branch develop

  # work from our base branch
  git checkout $base_branch

  # remove local tracking branches where the remote branch is gone
  git fetch -p

  # find all local branches that have been merged into the base branch
  # and delete any without a corresponding remote branch
  set local
  for f in (git branch --merged $base_branch | grep -v "\(master\|$base_branch\|\*\)" | awk '/\s*\w*\s*/ {print $1}')
    set local $local $f
  end

  set remote
  for f in (git branch -r | xargs basename)
    set remote $remote $f
  end

  for f in $local
    echo $remote | grep --quiet "\s$f\s"
    if [ $status -gt 0 ]
      git branch -d $f
    end
  end
end

几点注意事项

确保设置正确的base_branch。在本例中,我使用develop作为基本分支,但它可以是任何东西。

这一部分非常重要:grep-v“\(master\|$base_branch\|\*\)”。它确保您不会删除主分支或基本分支。

我使用gitbranch-d<branch>作为额外的预防措施,以便不删除任何尚未与上游或当前HEAD完全合并的分支。

一种简单的测试方法是用echo“将删除$f”替换gitbranch-d$f。

我想我还应该补充一句:使用风险自负!

其他回答

这些答案中的大多数实际上并没有回答最初的问题。我做了大量的挖掘,这是我找到的最干净的解决方案。这是一个稍微更彻底的答案:

查看默认分支。通常是git结账大师运行git fetch-p&&git branch-vv|awk'/:gone]/{print$1}'|xargs git branch-d

说明:

通过修剪跟踪分支,然后在gitbranch-vv中删除显示它们已“消失”的本地分支。

笔记:

如果您的语言设置为英语以外的语言,则需要更改为相应的单词。仅本地的分支将不会被触摸。已在远程删除但未合并的分支将显示通知,但不会在本地删除。如果您想删除这些,也可以将-d更改为-d。

git远程修剪源修剪跟踪不在远程上的分支。

gitbranch——merged列出已合并到当前分支中的分支。

xargs git branch-d删除标准输入中列出的分支。

请小心删除gitbranch--merged列出的分支。该列表可能包含您不希望删除的主分支或其他分支。

要在删除分支之前让自己有机会编辑列表,可以在一行中执行以下操作:

git branch --merged >/tmp/merged-branches && \
  vi /tmp/merged-branches && xargs git branch -d </tmp/merged-branches

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

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

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

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

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

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