Mai*_*tel 996 git git-branch
是否有一种简单的方法可以删除远程等效不再存在的所有跟踪分支?
例:
分支机构(本地和远程)
在本地,我只有一个主分支.现在我需要处理bug-fix-a,所以我检查它,处理它,并将更改推送到远程.接下来我用bug-fix-b做同样的事情.
分支机构(本地和远程)
现在我有本地分支机构master,bug-fix-a,bug-fix-b.Master分支维护者将我的更改合并到master中并删除他已经合并的所有分支.
那么现在的状态是:
分支机构(本地和远程)
现在我想调用一些命令删除分支(在本例中为bug-fix-a,bug-fix-b),这些分支不再在远程存储库中表示.
它会像现有的命令git remote prune origin,但更像是git local prune origin.
aub*_*pwd 1126
git remote prune origin 修剪跟踪分支不在遥控器上.
git branch --merged 列出已合并到当前分支的分支.
xargs git branch -d 删除标准输入上列出的分支.
小心删除列出的分支git branch --merged.该列表可能包含master您不想删除的分支或其他分支.
要在删除分支之前给自己编辑列表的机会,可以在一行中执行以下操作:
git branch --merged >/tmp/merged-branches && vi /tmp/merged-branches && xargs git branch -d </tmp/merged-branches
jas*_*man 497
命令之后
git fetch -p
Run Code Online (Sandbox Code Playgroud)
运行时删除远程引用
git branch -vv
Run Code Online (Sandbox Code Playgroud)
它将显示为"已离开"作为远程状态.例如,
$ git branch -vv
master b900de9 [origin/master: behind 4] Fixed bug
release/v3.8 fdd2f4e [origin/release/v3.8: behind 2] Fixed bug
release/v3.9 0d680d0 [origin/release/v3.9: behind 2] Updated comments
bug/1234 57379e4 [origin/bug/1234: gone] Fixed bug
Run Code Online (Sandbox Code Playgroud)
因此,您可以编写一个简单的脚本来删除已经转移的本地分支:
git fetch -p && for branch in `git branch -vv | grep ': gone]' | awk '{print $1}'`; do git branch -D $branch; done
Run Code Online (Sandbox Code Playgroud)
dls*_*sso 273
这些答案中的大多数实际上并未回答原始问题.我做了一堆挖掘,这是我找到的最干净的解决方案.这是一个稍微更全面的答案:
git checkout mastergit fetch -p && git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d说明:
通过修剪您的跟踪分支然后删除显示它们"已消失"的本地分支来工作git branch -vv.
笔记:
如果您的语言设置为英语以外的其他语言,则需要更改gone为相应的单词.不会触及仅限本地的分支.已在远程删除但未合并的分支将显示通知但不会在本地删除.如果你想删除那些以及更改-d为-D.
And*_*cer 170
我通常不会回答已有16个答案的问题,但所有其他答案都是错误的,正确的答案是如此简单.问题是,"是否有一种简单的方法可以删除远程等效不再存在的所有跟踪分支?"
如果"简单"意味着不脆弱,没有危险,并且不依赖于并非所有读者都会拥有的工具,那么正确答案是:不.
有些答案很简单,但他们并没有按照要求做.其他人做了所要求的,但并不简单:所有人都依赖于通过文本操作命令或脚本语言解析Git输出,这些语言可能不会出现在每个系统上.最重要的是,大多数建议使用瓷器命令,其输出不是设计为由脚本解析("瓷器"是指用于人工操作的命令;脚本应使用较低级别的"管道"命令).
进一步阅读:
如果你想安全地这样做,对于问题中的用例(垃圾收集跟踪分支已经在服务器上删除但仍然作为本地分支存在)和仅使用高级Git命令,你必须
git fetch --prune(或者git fetch -p,这是一个别名,或者git prune remote origin在没有提取的情况下做同样的事情,并且可能不是你想要的大部分时间).git branch -v(任何孤立的跟踪分支将被标记为"[已消失]").git branch -d [branch_name] 在每个孤立的跟踪分支上如果你想编写一个解决方案的脚本,那么for-each-ref就是你的起点,就像马克·朗格尔在这里的答案和另一个问题的答案一样,但是我没有办法在没有编写shell脚本循环或使用xargs之类的情况下利用它.
要了解正在发生的事情,您需要意识到,在跟踪分支的情况下,您没有一个分支,而是三个分支.(并且回想一下"分支"仅仅意味着指向提交的指针.)
给定跟踪分支feature/X,远程存储库(服务器)将具有此分支并调用它feature/X.你的本地存储库有一个分支remotes/origin/feature/X,意思是"这就是遥控器告诉我它的功能/ X分支是什么,上次我们谈过",最后,本地存储库有一个分支feature/X指向你的最新提交,并配置为"轨道" remotes/origin/feature/X,意味着你可以拉动并推动它们保持对齐.
在某些时候,有人删除feature/X了遥控器上的.从那一刻起,你就离开了你的本地feature/X(你可能不再需要了,因为功能X上的工作可能已经完成了),而你remotes/origin/feature/X的当然无用,因为它的唯一目的是记住服务器分支的状态.
并且Git会让你自动清理冗余remotes/origin/feature/X- 这就是做什么git fetch --prune- 但由于某种原因,它不会让你自动删除你自己的feature/X...即使你feature/X仍然包含孤立的跟踪信息,所以它有信息识别已完全合并的以前跟踪分支.(毕竟,它可以为您提供让您自己手动操作的信息.)
kar*_*gen 51
我在这里找到了答案: 如何删除已合并的所有git分支?
git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
Run Code Online (Sandbox Code Playgroud)
您可以master通过grep在第一个分支之后添加另一个分支来确保不会删除该分支或任何其他分支.在那种情况下你会去:
git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d
Run Code Online (Sandbox Code Playgroud)
因此,如果我们想继续保持master,develop并staging举例来说,我们会去:
git branch --merged | grep -v "\*" | grep -v "master" | grep -v "develop" | grep -v "staging" | xargs -n 1 git branch -d
Run Code Online (Sandbox Code Playgroud)
由于它有点长,您可能想要为您的.zshrc或添加别名.bashrc.我被称为gbpurge(for git branches purge):
alias gbpurge='git branch --merged | grep -v "\*" | grep -v "master" | grep -v "develop" | grep -v "staging" | xargs -n 1 git branch -d'
Run Code Online (Sandbox Code Playgroud)
然后重新加载你的.bashrc或.zshrc:
. ~/.bashrc
Run Code Online (Sandbox Code Playgroud)
要么
. ~/.zshrc
Run Code Online (Sandbox Code Playgroud)
Mai*_*tel 47
似乎解决方案在这里 - /sf/answers/75052491/
总之,git remote prune是否有魔力
chr*_*389 32
对于Microsoft Windows Powershell:
git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
git checkout master 切换到主分支
git remote update origin --prune 修剪远程分支
git branch -vv得到所有分支的详细输出(git引用)
Select-String -Pattern ": gone]" 只获取从远程删除它们的记录.
% { $_.toString().Trim().Split(" ")[0]} 获取分支名称
% {git branch -d $_} 删除分支
cs0*_*s01 31
删除已合并为master的所有分支,但不要尝试删除master本身:
git checkout master && git pull origin master && git fetch -p && git branch -d $(git branch --merged | grep master -v)
或添加别名:
alias gitcleanlocal="git checkout master && git pull origin master && git fetch -p && git branch -d $(git branch --merged | grep master -v)"
说明:
git checkout master 结账主分公司
git pull origin master 确保本地分支已合并所有远程更改
git fetch -p 删除对已删除的远程分支的引用
git branch -d $(git branch master --merged | grep master -v) 删除已合并为master的所有分支,但不要尝试删除master本身
Pra*_*tti 30
虽然上面的答案涵盖了如何手动修剪分支,但这个答案增加了自动化来解决这个问题。git现在有一个新的设置来修剪不再在每个获取操作的远程上的陈旧分支。这很棒,因为我们不再需要remote prune每次删除分支时都手动调用(git pull也调用git fetch)。
要在全局配置中启用此功能:
git config --global fetch.prune true
Run Code Online (Sandbox Code Playgroud)
让事情自动发生意味着您可能会忘记在新机器上添加此设置。它就是有效的。
git config --global remote.<name>.prune true
Run Code Online (Sandbox Code Playgroud)
我们也可以在不使用该标志的情况下应用相同的命令进行本地修剪--global。
上述命令适用于全局和局部,.gitconfig如下所示:
...
[fetch]
prune = true
Run Code Online (Sandbox Code Playgroud)
我建议将其添加到 ansible 配置或您的 dotfiles 存储库 ( .gitconfig) 中,以便将来自动进行设置。
配置设置在每次获取时调用以下命令:
git remote prune <remote name>
Run Code Online (Sandbox Code Playgroud)
要修剪引用作为正常工作流程的一部分,而不需要记住运行它,请在配置中fetch.prune全局或按远程设置。remote.<name>.prune请参阅git-config。
Sve*_*ens 29
你可以这样做:
git branch -vv | grep 'origin/.*: gone]' | awk '{print $1}' | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)
PS:正如Sam H.
首先执行这个:
git remote prune origin
Run Code Online (Sandbox Code Playgroud)
nor*_*raj 26
删除所有不在远程的本地分支
git fetch -p && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -D
Run Code Online (Sandbox Code Playgroud)
删除所有不在远程且已完全合并且未如之前许多答案中所述使用的本地分支。
git fetch -p && git branch --merged | grep -v '*' | grep -v 'master' | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)
git fetch -p 将修剪远程不再存在的所有分支git branch -vv will print local branches and pruned branch will be tagged with gonegrep ': gone]' selects only branch that are goneawk '{print $1}' filter the output to display only the name of the branchesxargs git branch -D will loop over all lines (branches) and force remove this branchWhy git branch -D and not git branch -d else you will have for branches that are not fully merged.
error: The branch 'xxx' is not fully merged.
Run Code Online (Sandbox Code Playgroud)
Pat*_*irk 25
大多数其他解决方案中"消失"的模式匹配对我来说有点吓人.为了更安全,它使用--format标志来提取每个分支的上游跟踪状态.
我需要一个Windows友好版本,所以这将使用Powershell删除列为"已消失"的所有分支:
git branch --list --format "%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)" |
? { $_ -ne "" } |
% { git branch -D $_ }
Run Code Online (Sandbox Code Playgroud)
第一行列出了上游分支"已消失"的本地分支的名称.下一行删除空白行(对于未"消失"的分支输出),然后将分支名称传递给命令以删除分支.
Him*_*ura 21
另一个答案,因为没有一个解决方案适合我对优雅和跨平台的需求:
删除不在远程的本地分支的命令:
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
Run Code Online (Sandbox Code Playgroud)
将它与 gitconfig 集成,以便它可以运行 git branch-prune:
重击
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'
Run Code Online (Sandbox Code Playgroud)
电源外壳
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'
Run Code Online (Sandbox Code Playgroud)
(需要帮助寻找 PowerShell 和 bash 的通用命令)
git branch-prune向您的 git添加命令git for-each-ref--filter不需要外部依赖的情况下完成的~\.gitconfig. 执行此操作后,您可以简单地执行git branch-pruneAsa*_*af 18
你可以使用这个:
git fetch --prune
Run Code Online (Sandbox Code Playgroud)
然后
git branch -vv | egrep -v "([origin/[a-zA-Z0-9/_-]+])" | awk "{print $1}" | xargs git branch -D
Run Code Online (Sandbox Code Playgroud)
它删除所有未链接到远程的本地分支
我亲自添加了一个别名来为我做这件事
alias gbs='git fetch --prune; git branch -vv | egrep -v "(\[origin\/[a-zA-Z0-9/_-]+\])" | awk "{print \$1}" | xargs git branch -D'
Run Code Online (Sandbox Code Playgroud)
cki*_*ey3 14
git fetch -p
Run Code Online (Sandbox Code Playgroud)
这将删除未远程跟踪的所有分支.
Fra*_*ois 14
可能对某些简单的一行有用,可以清除除master和develop之外的所有本地分支
git branch | grep -v "master" | grep -v "develop" | xargs git branch -D
Run Code Online (Sandbox Code Playgroud)
kar*_*bal 14
因为有些答案不\xe2\x80\x99t防止意外删除
\ngit fetch -p && LANG=c git branch -vv | awk '/: gone]/&&!/^\\*/{print $1}' | xargs git branch -d
*过滤掉第一列中的分支很重要。
Mar*_*air 13
我认为没有内置命令可以执行此操作,但执行以下操作是安全的:
git checkout master
git branch -d bug-fix-a
Run Code Online (Sandbox Code Playgroud)
当你使用时-d,git将拒绝删除分支,除非它完全合并到HEAD其上游远程跟踪分支.因此,您可以始终循环输出git for-each-ref并尝试删除每个分支.这种方法的问题在于我怀疑你可能不想bug-fix-d因为origin/bug-fix-d包含其历史而被删除.相反,您可以创建类似以下内容的脚本:
#!/bin/sh
git checkout master &&
for r in $(git for-each-ref refs/heads --format='%(refname:short)')
do
if [ x$(git merge-base master "$r") = x$(git rev-parse --verify "$r") ]
then
if [ "$r" != "master" ]
then
git branch -d "$r"
fi
fi
done
Run Code Online (Sandbox Code Playgroud)
警告:我没有测试过这个脚本 - 只能小心使用...
pab*_*a98 13
这将删除除本地主引用和当前正在使用的引用之外的所有合并本地分支:
git branch --merged | grep -v "*" | grep -v "master" | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)
这将删除已从" origin " 引用的远程存储库中删除的所有分支,但仍在" remotes/origin "中本地可用.
git remote prune origin
Run Code Online (Sandbox Code Playgroud)
bxm*_*bxm 10
还有另一个答案,大量来自/sf/answers/3388808811/(我喜欢它,因为它似乎消除gone]了git branch输出中匹配位置的任何歧义)但添加了*nix弯曲:
git branch --list --format "%(if:equals=[gone])%(upstream:track)%(then)%(refname)%(end)" \
| sed 's,^refs/heads/,,;/^$/d' \
| xargs git branch -D
Run Code Online (Sandbox Code Playgroud)
我把它包含git-gone在我的路径上的脚本中:
#!/usr/bin/env bash
action() {
${DELETE} && xargs git branch -D || cat
}
get_gone() {
git branch --list --format "%(if:equals=[gone])%(upstream:track)%(then)%(refname)%(end)" \
| sed 's,^refs/heads/,,;/^$/d'
}
main() {
DELETE=false
while [ $# -gt 0 ] ; do
case "${1}" in
(-[dD] | --delete) DELETE=true ;;
esac
shift
done
get_gone | action
}
main "${@}"
Run Code Online (Sandbox Code Playgroud)
NB - --format选项似乎相当新; 我需要将git从2.10.something升级到2.16.3才能获得它.
我发现基于 Powershell 的解决方案比这里的许多实现更清晰。
# prune deleted remoted branches
git fetch -p
# get all branches and their corresponding remote status
# deleted remotes will be marked [gone]
git branch -v |
#find ones marked [gone], capture branchName
select-string -Pattern '^ (?<branchName>\S+)\s+\w+ \[gone\]' |
foreach-object{
#delete the captured branchname.
git branch -D $_.Matches[0].Groups['branchName']
}
Run Code Online (Sandbox Code Playgroud)
小智 7
grep gone <(git branch -v) | cut -d ' ' -f 3 | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)
上面的命令可用于获取在远程中合并和删除的分支,并删除在远程中不再可用的本地分支
根据上面的信息,这对我有用:
git br -d `git br -vv | grep ': gone] ' | awk '{print $1}' | xargs`
Run Code Online (Sandbox Code Playgroud)
它会删除': gone] '远程所有本地分支.
这些都不适合我。我想要一种能够清除所有正在跟踪远程分支的本地分支的方法,该分支位于origin已删除(gone)的远程分支。我不想删除从未设置为跟踪远程分支的本地分支(即:我的本地dev分支)。我还想要一个仅使用git或其他简单的CLI工具的简单的一线工具,而不是编写自定义脚本。我最终使用了grep和awk做这个简单的命令。
最终这就是我的结果~/.gitconfig:
[alias]
prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -D
Run Code Online (Sandbox Code Playgroud)
这是一个git config --global ...可以轻松将其添加为的命令git prune-branches:
git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'
Run Code Online (Sandbox Code Playgroud)
注意:在config命令中,我使用-d选项git branch而不是-D,就像在实际配置中一样。我使用它-D是因为我不想听到Git关于合并分支的抱怨。您可能还需要此功能。如果是这样,只需在config命令的末尾使用-D而不是即可-d。
从大量图纸数量 的 其他 的答案在这里,我已经结束了与以下(GIT 2.13及以上的只有,我相信),它应该在任何运行类UNIX外壳:
git for-each-ref --shell --format='ref=%(if:equals=[gone])%(upstream:track)%(then)%(refname)%(end)' refs/heads | while read entry; do eval "$entry"; [ ! -z "$ref" ] && git update-ref -d "$ref" && echo "deleted $ref"; done
Run Code Online (Sandbox Code Playgroud)
这特别使用了for-each-ref而不是branch(因为它branch是为人类可读的输出而设计的“瓷器”命令,而不是机器处理)并使用其--shell参数来获得正确转义的输出(这使我们不必担心引用名称中的任何字符)。
| 归档时间: |
|
| 查看次数: |
377722 次 |
| 最近记录: |