使用< code > git remote prune origin ,我可以删除不再位于远程的本地分支。
但是我还想删除从那些远程分支创建的本地分支(最好检查一下它们是否未合并)。
我该怎么做?
修剪之后,您可以使用< code>git branch -r获得远程分支的列表。可以使用< code>git branch -vv检索带有远程跟踪分支的分支列表。因此,使用这两个列表,您可以找到不在远程列表中的远程跟踪分支。
这一行应该可以(需要< code>bash或< code>zsh,不能与标准的Bourne shell一起使用):
git fetch -p ; git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d
该字符串获取远程分支的列表,并通过标准输入将其传递到< code>egrep中。并过滤具有远程跟踪分支的分支(使用< code>git branch -vv并过滤具有< code>origin的分支),然后获取输出的第一列,这将是分支名称。最后,将所有分支名称传递给删除分支命令。
由于它使用-d
选项,因此它不会删除运行此命令时尚未合并到您所在分支中的分支。
如果要删除已经合并到主服务器的所有本地分支,可以使用以下命令:
git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d
如果使用 main
作为主分支,则应相应地修改命令:
git branch --merged main | grep -v '^[ *]*main$' | xargs git branch -d
更多信息。
在 git help fetch
提供的信息中,有这样一个小项目:
-p, --prune
After fetching, remove any remote-tracking branches which no longer exist on the remote.
所以,也许,git fetch-p
就是你要找的?
编辑:好吧,对于那些在事实发生3年后仍在争论这个答案的人来说,这里有更多关于我为什么给出这个答案的信息。。。
首先,OP说他们希望“也删除那些从远程分支创建的本地分支[它们不再在远程上]”。这在< code>git中是不可能的。这里有一个例子。
假设我在中央服务器上有一个存储库,它有两个分支,称为 A
和 B
。如果我将该存储库克隆到我的本地系统,我的克隆将具有称为 origin/A
和 origin/B
的本地引用(还不是实际分支)。现在假设我执行以下操作:
git checkout -b A origin/A
git checkout -b Z origin/B
git checkout -b C <some hash>
这里的相关事实是,出于某种原因,我选择在本地repo上创建一个名称与其源不同的分支,并且我还有一个本地分支,该分支(尚未)存在于源repo上。
现在,假设我删除了远程repo上的A
和B
分支,并更新了我的本地repo(某种形式的git fetch
),这会导致我的本地refsorigin/A
andorigin/B
消失。现在,我的本地回购仍有三个分支,A
、Z
和C
。其中没有一个在远程回购上有相应的分支。其中两个是“从…远程分支创建的”,但即使我知道在原点上曾经有一个名为B
的分支,我也无法知道Z
是从B
创建的,因为它在这个过程中被重命名了,这可能是有充分理由的。因此,实际上,如果没有一些外部进程记录分支源元数据,或者没有了解历史的人,就不可能判断OP要删除三个分支中的哪一个(如果有的话)。如果没有git
不会自动为您维护的一些外部信息,git fetch-p
就已经尽可能接近了,而且任何自动尝试OP要求的方法都有可能删除太多分支,或者错过一些OP想要删除的分支。
还有其他的情况,例如,如果我从< code>origin/A创建三个单独的分支来测试三种不同的方法,然后< code>origin/A就消失了。现在我有三个分支,它们显然不能在名称上完全匹配,但是它们是从< code>origin/A创建的,因此对OPs问题的字面解释需要删除这三个分支。然而,如果你能找到一种可靠的方法来匹配它们,这可能并不理想...