是否有一种简单的方法可以删除所有远程对等分支不再存在的跟踪分支?
例子:
分支机构(本地和远程)
主人原始/主起源/bug-fix-a起源/bug-fix-b起源/bug-fix-c
在本地,我只有一个主分支。现在我需要处理bug-fix-a,所以我检查它,处理它,并将更改推到远程。接下来,我对bug-fix-b做同样的操作。
分支机构(本地和远程)
主人bug-fix-abug-fix-b型原始/主起源/bug-fix-a起源/bug-fix-b起源/bug-fix-c
现在我有本地分支机构master,bug-fix-a,bug--fix-b。主分支维护者将把我的更改合并到主分支中,并删除他已经合并的所有分支。
因此,当前状态为:
分支机构(本地和远程)
主人bug-fix-abug-fix-b型原始/主起源/bug-fix-c
现在我想调用一些命令来删除分支(在本例中为bug-fix-a、bug-fix-b),这些分支在远程存储库中不再表示。
它类似于现有命令git remote prune origin,但更类似于git local prune origin。
真正的挑战是当维护者压缩提交时。然后,使用git内置功能(如--merged)的解决方案没有帮助。
gitdelete合并分支工具允许方便地删除分支。我特别喜欢互动模式。
安装(需要python3):
pip install git-delete-merged-branches
然后执行
git-delete-merged-branches --effort=3
--努力=3对于能够删除挤压的分支很重要。
选择
@teppeis/git delete squashed:安装node.js后,执行npx@teppeis/git delete squushed。支持主分支。git delete squashed:未维护:主分支的未命中功能@teppeis/git delete squashed基于此。
虽然上面的答案涵盖了如何手动修剪树枝,但这个答案增加了解决这一问题的自动化。git现在有了一个新设置,可以在每次提取操作中删除不再位于远程的过时分支。这很好,因为我们不再需要在每次删除分支时手动调用远程prune(git pull也调用git fetch)。
为每次提取启用修剪行为
要在全局配置中启用此功能,请执行以下操作:
git config --global fetch.prune true
让事情自动发生意味着你可以忘记在新机器上添加此设置。它只是起作用。
对特定远程设备上的每次提取启用修剪行为
git config --global remote.<name>.prune true
本地自动修剪
我们也可以在不使用--global标志的情况下对局部修剪应用相同的命令。
.git配置
上面的命令适用于global和local.gitconfig,如下所示:
...
[fetch]
prune = true
我可以建议将其添加到一个可靠的配置中或添加到您的dotfiles存储库(.gitconfig)中,以便将来自动进行设置。
配置设置在每次提取时调用以下命令:
git remote prune <remote name>
总结
要将引用作为正常工作流的一部分进行删减而不需要记住运行,请全局或远程设置fetch.prune<name>.在配置中对每个远程进行修剪。请参阅git-config。
另一个答案。
如果你正在寻找一些新奇的东西,这里是我在fzf中使用的别名。
LANG=C git for-each-ref --sort=-committerdate --format '%(refname:short) %(upstream:track)' refs/heads \
| awk '$2 == "[gone]" {print $1}' \
| fzf --multi --bind ctrl-a:select-all,ctrl-t:toggle-all \
--preview='git log --color=always --graph --format=compact {1}' \
--header='Select [gone] branch to remove' \
--header-first --reverse \
| xargs --no-run-if-empty git branch -d
解释:
强制LANG=C以避免[gone]模式上的本地化对每个引用使用git,以避免git分支中的任何格式更改使用awk过滤。我尝试使用--format=“%(if:equals=[gone])%…”,但这意味着要管理空行。使用fzf选择要删除的分支。添加快捷键:[ctrl-a]选择全部,[ctrl-t]反转选择([tab]照常选择)。您可以使用[enter]进行验证,也可以使用[esc]中止。我使用这个分支选择器作为确认阶段。在右侧显示所选分支的日志(以记住日期和内容…)。我使用下面列出的紧凑格式。您可以使用任何(不太宽)日志格式。--如果为空,则不运行。它不是强制性的,有助于避免在中止进程时出错(与没有分支名称的gitbranch-d相关)。
别名可能看起来很糟糕:
[alias]
gone = "!f() { LANG=C git for-each-ref --sort=-committerdate --format '%(refname:short) %(upstream:track)' refs/heads | awk '$2 == \"[gone]\" {print $1}' | fzf --multi --bind ctrl-a:select-all,ctrl-t:toggle-all --preview='git log --color=always --graph --format=compact {1}' --header='Select [gone] branch to remove' --header-first --reverse | xargs --no-run-if-empty git branch -d ; }; f"
[pretty]
compact = %Cred%h%Creset%C(auto)%d%Creset%n Author: %an <%aE>%n Date: %cd%n %s
(与上文相同,“)
我在这里找到了答案:如何删除所有已合并的git分支?
git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
确保我们留住主人
您可以通过在第一个grep之后添加另一个grep来确保master或其他分支不会被删除。在这种情况下,您可以:
git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d
因此,如果我们想保持主控、开发和登台,我们会:
git branch --merged | grep -v "\*" | grep -v "master" | grep -v "develop" | grep -v "staging" | xargs -n 1 git branch -d
将此设置为别名
由于它有点长,您可能需要在.zshrc或.bashrc中添加别名。我的别名称为gbpurge(用于git分支清除):
alias gbpurge='git branch --merged | grep -v "\*" | grep -v "master" | grep -v "develop" | grep -v "staging" | xargs -n 1 git branch -d'
然后重新加载.bashrc或.zshrc:
. ~/.bashrc
or
. ~/.zshrc