我在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存在,我宁愿使用某种类型的比较函数。
答案 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> prune
或git 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
。