有没有一种简单的方法来删除其远程等效不再存在的所有跟踪分支?
例子:
分支(本地和远程)
大师
原点 / 母版
origin / bug-fix-a
origin / bug-fix-b
origin / bug-fix-c
在本地,我只有一个主分支。现在我需要在bug-fix-a上工作,所以我检查出来,处理它,并将更改推送到远程。接下来我对bug-fix-b做同样的事情。
分支(本地和远程)
大师
bug-fix-a
bug-fix-b
原点 / 母版
origin / bug-fix-a
origin / bug-fix-b
origin / bug-fix-c
现在我有了本地分支master、bug-fix-a、bug-fix-b。Master 分支维护者会将我的更改合并到master中,并删除他已经合并的所有分支。
所以现在的状态是:
分支(本地和远程)
大师
bug-fix-a
bug-fix-b
原点 / 母版
origin / bug-fix-c
现在我想调用一些命令来删除分支(在这种情况下bug-fix-a,bug-fix-b),这些分支不再在远程存储库中表示。
它类似于现有的命令git remote prune origin
,但更像git local prune origin
。
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
最安全的方法是将“管道”命令git for-each-ref
与插值变量%(upstream:track)
一起使用,当分支不再位于远程时,该变量将为[gone]
:
git fetch -p && for branch in $(git for-each-ref --format '%(refname) %(upstream:track)' refs/heads | awk '$2 == "[gone]" {sub("refs/heads/", "", $1); print $1}'); do git branch -D $branch; done
这种方法比使用“瓷器”命令更安全,因为没有在提交消息的一部分上意外匹配的风险。
git fetch -p && for branch in $(git branch -vv | grep ': gone]' | awk '{print $1}'); do git branch -D $branch; done
这样的工作方式是,在命令
git fetch -p
删除远程引用,当您运行
git branch -vv
它将显示“gone”作为远程状态。例如,
$ 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
这是脚本迭代的内容。
这些答案中的大多数实际上并没有回答原始问题。我做了一堆挖掘和this是我找到的最干净的解决方案。这里是该答案的稍微更彻底的版本:
检查您的默认分支。通常git checkout master
git fetch-p &&git branch-vv | awk '/:gone]/{print $1}' | xargs git branch-d
说明:
通过修剪您的跟踪分支,然后删除显示它们在git branch -vv
中“消失”的本地分支。
如果您的语言设置为英语以外的其他语言,则需要将gone
更改为相应的单词。仅本地分支不会被触及。已在远程删除但未合并的分支将显示通知,但不会在本地删除。如果您还想删除它们,请将-d
更改为-D
。
我通常不会回答一个已经有 16 个答案的问题,但是所有其他答案都是错误的,正确的答案是如此简单。问题说:“是否有一种简单的方法可以删除远程等效不再存在的所有跟踪分支?”
如果“简单”意味着一次性删除它们,而不是脆弱,不危险,并且不依赖并非所有读者都会拥有的工具,那么正确的答案是:不。
有些答案很简单,但他们没有按照要求去做。其他人则按照要求去做,但并不简单:所有这些都依赖于通过文本操作命令或脚本语言解析 Git 输出,这可能并非在每个系统上都存在。最重要的是,大多数建议使用瓷器命令,其输出并非设计为由脚本解析(“瓷器”是指用于人类操作的命令;脚本应使用较低级别的“管道”命令)。
进一步阅读:
why you shouldn't pgit branch
output in a script.
tracking branches and the differences betweengit remote prune
,git prune
,git fetch--prune
如果您想安全地执行此操作,对于问题中的用例(已在服务器上删除但仍作为本地分支存在的垃圾收集跟踪分支),并且仅使用高级 Git 命令,您必须
git fetch --prune
(或git fetch -p
,这是一个别名,或git prune remote origin
,它在不获取的情况下执行相同的操作,并且可能不是您大多数时候想要的)。
请注意所有报告为已删除的远程分支。或者,要稍后查找它们,请git branch -v
(任何孤立的跟踪分支都将标记为“[gone]”)。
每个孤立跟踪分支上的git branch -d [branch_name]
(这是其他一些答案提出的)。
如果你想编写一个解决方案,那么for-each-ref
是你的起点,就像Mark Longair's answer这里和this answer to another question,但我看不到一种方法来利用它而不编写一个 shell 脚本循环,或使用 xargs 或东西。
背景说明
要理解正在发生的事情,您需要理解,在跟踪分支的情况下,您没有一个分支,而是三个分支(并记住“分支”只是指向提交的指针)。
给定一个跟踪分支feature/X
,远程存储库(服务器)将具有此分支并将其称为feature/X
。您的本地存储库有一个分支remotes/origin/feature/X
,意思是“这是远程告诉我的功能 / X 分支,上次我们交谈时”,最后,本地存储库有一个分支feature/X
指向您的最新提交,并配置为“
在某些时候,有人删除了遥控器上的feature/X
。从那一刻起,您将剩下本地的feature/X
(您可能不再想要它,因为功能 X 的工作可能已经完成)和remotes/origin/feature/X
,这肯定是无用的,因为它的唯一目的是记住服务器分支的状态。
Git 可以让你自己自动清理多余的remotes/origin/feature/X
— — 这就是git fetch --prune
所做的 — — 但是由于某种原因,它不允许你自动删除你自己的feature/X
...即使你的feature/X
仍然包含孤立的跟踪信息,所以它有信息来识别已经完全合并的前跟踪分支。(毕竟,它可以给你
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(60条)