繁体   English   中英

删除不再在Github上的所有分支

[英]Delete all branches that are no longer on Github

我在GitHub上有Branch-Master,Branch-A,Branch-B,Branch-C分支。 我通常合并为master并删除合并的分支。 这在我的本地机器上留下了一堆分支,但不是GitHub。

如何自动自动删除本地分支? 我想创建一个git钩子来做到这一点。

当我尝试

git remote prune origin

然后运行git branch,我仍然看到我的所有分支,甚至是那些合并并删除到master中的分支。

我知道我能做到

git branch -d {the_local_branch}

手动,但这在做githook或我有多个分支系统删除时没有帮助。

我不喜欢这里给出的答案: 如何删除已合并的所有Git分支?

它们是基于名称,并推断已删除的分支,而不是以某种方式显式传递特定于该分支的分支ID。 我在提供的链接中理解的是,如果我创建一个与已删除分支相同的分支名称,它也将被删除,即使它们是不同的分支。

如何在本地和远程删除Git分支?

不解决我的询问,因为它的解决方案已在上面说明。

如果它们存在,我宁愿使用分支uid的某种类型的比较函数。

您可以通过一个命令一次性删除所有分支(除了已签出的分支):

git branch --list | xargs git branch -D

如果要指定某个模式以匹配分支名称,您也可以这样做:

git branch --list k* | xargs git branch -D

并借助于

git remote prune origin

您可以删除系统中不再引用的远程分支。

希望这可以帮助 !

正如phd在评论中指出的那样,分支机构没有基础ID 分支名称就是在你的仓库,你或你的请求创建一个本地名称,标识一个具体的承诺。 您可以随时更改此名称,只要它符合分支名称的要求即可更改为您喜欢的任何字符串。 Git不会记得曾经有过其他名字。

现在,还有一些额外的信息:你的.git/config文件可以,并且通常会在其中,每个分支,一些注释,如:

[branch "master"]
    remote = origin
    merge = master

[branch "develop"]
    remote = another-remote
    merge = develop

这些设置定义分支的上游设置 一个分支根本没有上游 - 在这种情况下,两个设置不存在 - 或者一个上游,在这种情况下,两个设置存在并描述上游,使用旧的历史方法处理此前的两个部分发明了远程跟踪名称。

如果使用标准Git命令重命名分支,则会自动重命名这些配置节。 例如,在git branch -m develop xyz ,你将拥有:

[branch "xyz"]
    remote = another-remote
    merge = develop

这意味着你的本地分支xyz的上游是another-remote/develop (这假定标准fetch =远程another-remote 。)

通过一些努力,可以读取每个分支的上游设置(如果有的话):使用git for-each-ref枚举所有分支,然后,对于每个分支,使用git rev-parse --symbolic-full-name <branch>@{upstream}查看它是否有上游,如果是,上游名称是什么。 请注意,您必须要小心,因为“远程”可以设置为. ,表明某个本地分支的上游是另一个本地分支。

结合这种方案测试的(“确实分支X具有上游,并且如果是这样,它实际上是一个远程跟踪名称,和什么远程跟踪名字什么?”)与第二测试(“用后git remote <remote> prunegit fetch <remote> --prune ,远程跟踪名称是否存在?“)可以得到你想要的。 你需要做一些编码(例如bash脚本)。 使其最优化,或者在钩子内工作很难,但总体任务非常简单:

git for-each-ref --format='%(refname:short)' refs/heads |
while read branch; do
    # make sure it has an upstream set -- if not, ignore
    upstream=$(git rev-parse --symbolic-full-name ${branch}@{upstream}) || continue
    # make sure the upstream is a remote-tracking name
    case $upstream in
    refs/remotes/*) ;;
    *) continue;;
    esac
    # get the name of the remote
    remote=${upstream#refs/remotes/}
    remote=${remote%%/*}
    # prune remote-tracking branches
    git remote $remote prune
    # and test whether the upstream still exists
    git rev-parse $upstream && continue

    # $branch has upstream $upstream which is gone, so:
    echo git branch -D $branch
done

这是非常未经测试的,并且缺少重要的部分,例如保持它不会删除的分支(每个rev-parse将向stdout和/或stderr发送消息)。 它实际上也没有删除任何分支:因为它可能是相当不可恢复的,所以人们首先需要彻底测试它,然后才删除echo

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM