是否有一种简单的方法可以删除所有远程对等分支不再存在的跟踪分支?
例子:
分支机构(本地和远程)
主人原始/主起源/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。
Windows解决方案
对于Microsoft Windows Powershell:
git结帐主机;git远程更新原点--prune;git branch-vv|选择字符串-模式“:gone]”|%{$_.toString().Trim().Split(“”)[0]}|%{git branch-d$_}
解释
git checkout master切换到master分支
git远程更新原点--修剪远程分支
gitbranch-vv获取所有分支的详细输出(git引用)
选择String-Pattern“:gone]”仅获取从远程删除的记录。
%{$_.toString().Trim().Split(“”)[0]}获取分支名称
%{gitbranch-d$_}删除分支
git远程修剪源修剪跟踪不在远程上的分支。
gitbranch——merged列出已合并到当前分支中的分支。
xargs git branch-d删除标准输入中列出的分支。
请小心删除gitbranch--merged列出的分支。该列表可能包含您不希望删除的主分支或其他分支。
要在删除分支之前让自己有机会编辑列表,可以在一行中执行以下操作:
git branch --merged >/tmp/merged-branches && \
vi /tmp/merged-branches && xargs git branch -d </tmp/merged-branches
还有一个答案,因为没有一个解决方案符合我对优雅和跨平台的需求:
删除不在远程上的本地分支的命令:
for b in $(git for-each-ref --format='%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)' refs/heads); do git branch -d $b; done
要将其与gitconfig集成,以便可以使用git branch prune运行:
Bash
git config --global alias.branch-prune '!git fetch -p && for b in $(git for-each-ref --format='\''%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)'\'' refs/heads); do git branch -d $b; done'
PowerShell(PowerShell)
git config --global alias.branch-prune '!git fetch -p && for b in $(git for-each-ref --format=''%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)'' refs/heads); do git branch -d $b; done'
(需要帮助查找PowerShell和bash的通用命令)
为什么这个答案是最好的?
提供了一个完整的解决方案:向git添加一个git branch prune命令在Windows PowerShell中工作正常核心思想是@jason.rickman对每个裁判使用git的防弹方法分析和过滤是使用--filter完成的,因此不需要外部依赖项
说明:
在~\.gitconfig中添加新别名。执行此操作后,只需执行git分支修剪在此别名中:使用--prune标志获取分支,该标志“修剪不再位于远程的远程跟踪分支”对每个ref和--filter使用git,以获取分支列表(无远程)循环此列表并安全删除分支
另一个答案。
如果你正在寻找一些新奇的东西,这里是我在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
(与上文相同,“)