广州总部电话:020-85564311
广州总部电话:020-85564311

广州网站建设-小程序商城开发-广州小程序开发-企业微信开发公司-网站建设高端品牌-优网科技

20年
互联网应用服务商
请输入搜索关键词
知识库 知识库

优网知识库

探索行业前沿,共享知识宝库

清理已失效的分支
发布日期:2025-05-08 15:59:35 浏览次数: 823 来源:前端早读课


很久以前,我写过一套非常实用的 Git 别名,用来配合 GitHub Flow 工作流。其中我最喜欢的别名是 bdone,它会执行以下操作:

1、切换到默认分支;
2、运行 git up,确保本地代码是最新的;
3、运行 git bclean,删除所有已经合并到默认分支的本地分支。

这套流程在很长一段时间内都很好用。它的原理是列出所有已经合并到默认分支的分支,然后将它们删除。当时,我并不知道可以用 git branch --merged 来列出已合并的分支,所以没用这个命令。

不过,最近我加入了 PostHog 后,发现我的这些别名不太管用了。主要原因是,他们几乎在所有的代码库中合并 PR 时用的是 “Squash and Merge”。

当你使用 git merge --squash 或 GitHub 的 “Squash and merge” 功能时,Git 会在目标分支上创建一个新的提交,这个提交会把源分支的所有变更整合成一个单一的提交。但这个新的提交不会保留原先各个提交的任何引用。因此,Git 不会将源分支视为已合并,像 git branch --merged 这样的命令也不会显示这些分支。

【第3410期】如何将JavaScript单体代码库的Git大小缩小到原来的94%的?

不过,说到 Git,总是有办法的。

解决方法

当你在 GitHub 上合并一个 PR 后,界面上会出现一个 “Delete branch”(删除分支)按钮:

这是一个非常好的功能,能帮你及时清理已经合并到默认分支的分支。实际上,你还可以设置 GitHub,在合并后 “自动删除 head 分支”:

我非常推荐大家也这么做。当远程分支被删除后,Git 会把它标记为 “gone”(已不存在)。比如,当你运行 git branch -vv 时,会看到类似下面的输出:

 > git branch -vv

   haacked/decide-v4      ba39408 [origin/haacked/decide-v4: gone] Fix demo to handle variants
   haacked/fix-sample-app ec15751 [origin/haacked/fix-sample-app] Handle variants
 * haacked/local-only     e78d2f6 Do important stuff
   main                   ab885d0 [origin/main] chore: Bump to v1.0.2

注意,haacked/decide-v4 被标记为了 gone。

我们可以使用 Git 的 “高级命令” 以更易于解析的格式列出分支及其跟踪信息。

 git for-each-ref --format='%(refname:short) %(upstream:track)' refs/heads/

输出可能是这样的:

 haacked/decide-v4 [gone]
 haacked/fix-sample-app
 haacked/local-only
 master

接下来,我们可以创建一个别名,用来列出这些 gone 的分支:

 git config --global alias.gone "!git for-each-ref --format='%(refname:short) %(upstream:track)' refs/heads/ | awk '\$2 == \"[gone]\" { print \$1 }'"

现在我们可以使用别名来列出已删除的分支:

 git gone

 haacked/decide-v4

就能列出所有已经消失的分支了。

接着,我们可以更新之前的 bclean 别名,让它基于 gone 来删除这些分支:

 git config --global alias.bclean "!git gone | xargs -r git branch -D"

不幸的是,因为 Git 并不知道这些分支已经被合并,所以我们需要强制删除(-D)。虽然听起来有点可怕,但实际上这不会影响本地的其他分支,也不会删除仍在追踪远程分支的分支。使用这个别名,只需要运行 git bclean,就能清理掉所有已经合并到默认分支的本地分支。

【早阅】GitHub Copilot最佳实践

最后,bdone 别名也可以恢复原来的功能:切换到默认分支,执行 git up,再执行 bclean

多人协作场景下的建议

在多人协作的项目中,分支使用更加频繁,清理操作稍有不慎就可能影响他人工作。因此在使用本文方法时,建议结合以下实践:

【第3280期】从 Lerna 到现代化:原生 Workspaces 和 Changesets 的高效协作

1、统一分支命名规范

建议团队内部制定统一的分支命名规则,比如:

  • feature/xxx:新功能开发
  • bugfix/xxx:缺陷修复
  • hotfix/xxx:紧急修复
  • chore/xxx:日常维护任务
  • experiment/xxx:试验性开发

主分支建议统一为 main 或 master。

通过规范命名,可以更容易区分临时性分支与长期保留的主干分支,降低误删风险。

2、防止误删主分支

为了避免意外删除重要分支,可以在 bclean 命令中排除主分支,例如:

 git config --global alias.bclean "!git gone | grep -vE '^(main|master|develop)$' | xargs -r git branch -D"

这样,即使 main、master、develop 这些分支出现异常情况(例如被误标记为 gone),也不会被删除。

3、删除前增加确认提示(可选)

如果希望更加保险,可以在删除前列出待删除分支并进行人工确认,例如:

 git gone | grep -vE '^(main|master|develop)$' | tee /tmp/deletable-branches
 echo "即将删除以下分支:"
 cat /tmp/deletable-branches
 read -p "确认删除这些分支吗?(y/n): " confirm && [ "$confirm" = "y" ] && cat /tmp/deletable-branches | xargs -r git branch -D

这一步虽然多了一点交互,但对于多人协作项目,尤其是大型仓库来说,非常值得。

4、定期清理与团队协作

建议团队定期(例如每周、每两周)安排分支清理,或者通过 CI 工具自动生成失联分支清单并提醒开发者及时清理本地分支,保持仓库整洁高效。

完整的别名设置

你可以把下面的内容复制到你的 .gitconfig 文件中:

 [alias]
     default = "!git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'"
     bclean = "!git gone | xargs -r git branch -D"
     # 切换到指定分支(如果不指定则切换到默认分支),执行 git up,然后执行 bclean
     bdone = "!f() { DEFAULT=$(git default); git checkout ${1-$DEFAULT} && git up && git bclean; }; f"
     gone = "!git for-each-ref --format='%(refname:short) %(upstream:track)' refs/heads/ | awk '$2 == \"[gone]\" { print $1 }'"

如果你更喜欢通过命令行配置,也可以直接运行这些命令:

 git config --global alias.default "!git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'"
 git config --global alias.gone "!git for-each-ref --format='%(refname:short) %(upstream:track)' refs/heads/ | awk '\$2 == \"[gone]\" { print \$1 }'"
 git config --global alias.bclean "!git gone | xargs -r git branch -D"
 git config --global alias.bdone "!f() { DEFAULT=\$(git default); git checkout \${1:-\$DEFAULT} && git up && git bclean; }; f"

注意事项

在使用 git default 这个别名时,可能会遇到以下错误:

 fatal: ref refs/remotes/origin/HEAD is not a symbolic ref

这是因为这个别名依赖于 origin/HEAD 这个符号引用。有些情况下(比如刚克隆的新仓库)这个引用可能不存在。可以通过下面的命令修复:

 git remote set-head origin --auto

所以现在,我之前的工作流又恢复正常了。现在,每次合并 PR 后,只需运行 git bdone,就能自动清理分支了,世界再次恢复了秩序。


优网科技,优秀企业首选的互联网供应服务商

优网科技秉承"专业团队、品质服务" 的经营理念,诚信务实的服务了近万家客户,成为众多世界500强、集团和上市公司的长期合作伙伴!

优网科技成立于2001年,擅长网站建设、网站与各类业务系统深度整合,致力于提供完善的企业互联网解决方案。优网科技提供PC端网站建设(品牌展示型、官方门户型、营销商务型、电子商务型、信息门户型、DIY体验、720全景展厅及3D虚拟仿真)、移动端应用(手机站APP开发)、微信定制开发(微信官网、微信商城、企业微信)、微信小程序定制开发等一系列互联网应用服务。


我要投稿

姓名

文章链接

提交即表示你已阅读并同意《个人信息保护声明》

专属顾问 专属顾问
扫码咨询您的优网专属顾问!
专属顾问
马上咨询
联系专属顾问
联系专属顾问
联系专属顾问
扫一扫马上咨询
扫一扫马上咨询

扫一扫马上咨询

和我们在线交谈!