gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 14:21:36 32 4
gpt4 key购买 nike

我在 GitHub 上有分支 Branch-Master、Branch-A、Branch-B、Branch-C。我一般 merge 到master,删除 merge 的分支。这会在我的本地计算机上留下一堆分支,但不会在 GitHub 上留下。

如何自动删除本地分支?我想创建一个 git 钩子(Hook)来执行此操作。

当我尝试

git remote prune origin

然后运行 ​​git branch,我仍然可以看到我所有的分支,甚至是 merge 和删除到 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 存在,我宁愿使用某种类型的比较函数。

最佳答案

作为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

这意味着你本地分支的上游xyzanother-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 脚本)。使其最佳化或在一个钩子(Hook)内工作是很困难的,但总体任务非常简单:

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 .

关于git - 删除所有不再在 Github 上的分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56061869/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com