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

时间:2019-05-09 14:37:30

标签: git 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时无济于事,或者我有多个要系统删除的分支。

我不喜欢这里给出的答案: How can I delete all Git branches which have been merged?

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

How do I delete a Git branch locally and remotely?

由于上面已经说明了解决方案,因此无法解决我的问题。

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

2 个答案:

答案 0 :(得分:0)

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

git branch --list | xargs git branch -D

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

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

并在

的帮助下
git remote prune origin

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

希望这会有所帮助!

答案 1 :(得分:0)

phd noted in a comment一样,分支没有基础ID 。分支名称只是您或您的请求创建的您的存储库中的本地名称,用于标识一个特定的提交。您可以随时将其更改为自己喜欢的任何字符串,只要它符合the requirements for a branch name。 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}进行查看如果有上游,如果有,则上游的名字是什么。请注意,由于“ remote”可以设置为.,因此您在这里必须小心一点,这表示某个本地分支的上游是另一个本地分支。

结合这种编程测试(“分支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