我尝试过使用git remote -r
命令查看所有远程存在的分支,但我发现结果包括那些已从远程删除的分支。
有没有办法过滤掉这些“僵尸”分支呢?
我尝试过使用git remote -r
命令查看所有远程存在的分支,但我发现结果包括那些已从远程删除的分支。
有没有办法过滤掉这些“僵尸”分支呢?
这个问题有几个可能的潜在含义,因此它有几个可能的答案。关键问题是至少涉及两个不同的Git存储库。
在我们进入两个答案之前,先提一下远程仓库,它只是像origin
这样的简短名称。 远程仓库本身保存了Git调用其他Git的URL。 您可以拥有任意数量的远程仓库。 除了仅存储URL外,还可以对远程仓库进行其他操作,但存储URL是主要内容。 git remote
命令是与远程仓库交互的主要用户界面命令,但由于git clone
最初为您创建名为origin
的远程仓库,因此您几乎从不需要使用git remote
。
您的计算机上的Git会保存和更新您的 Git存储库。 您的Git具有您的分支名称、标记名称和其他名称以及提交集合。 提交集是Git与其他Git存储库共享的部分,尽管也有某些名称共享。
同时,因为您的Git之前调用过另一个Git,并在名称为origin
的情况下记住了该其他Git的URL,因此您的Git也记住了他们 Git的分支名称。 为此,您的Git在您的存储库中创建远程跟踪分支名称1,例如origin/master
。 这些名称只是记住,您的Git上一次调用位于origin
的另一个Git时,他们说他们的master
是某个特定的哈希ID。
当您运行git fetch origin
(或者如果只有一个名为origin
的远程仓库,则只需运行git fetch
),您的Git会在这一点上调用其他Git,获取它们拥有而您没有的任何新提交,并更新所有远程跟踪origin/*
名称。
运行git branch -r
将列出您的远程跟踪名称,因此git branch -r
向您展示了您的Git在使用他们的Git更新时看到的内容。 请注意,git branch -a
包括git branch -r
,但在origin/master
名称前面添加了remotes/
单词。2
然而,这里会发生一个问题,他们可能会删除一些分支名称。例如,昨天他们的Git有一个名为feature/tall
的分支,但现在已经没有了。你的Git昨天调用了他们的Git,并创建或更新了origin/feature/tall
以匹配他们的feature/tall
。现在你的Git再次调用他们的Git,他们却没有列出一个feature/tall
。
默认情况下,你的Git不做任何操作。
如果运行git fetch --prune
,你的Git像往常一样调用他们的Git,列出所有的分支名称,并发现你有一个过期的origin/feature/tall
,它是在他们还有feature/tall
时创建的,并删除它。
因此,通常情况下,你应该向每个git fetch
添加--prune
,这样当你的Git注意到它们过期时(但不是之前),你的Git的远程跟踪名称将被删除。你可以配置你的Git自动执行此操作:
git config fetch.prune true
你可以通过以下方式将此设置为Git的所有存储库(无论是在您的笔记本电脑还是其他计算机上)的默认值:
git config --global fetch.prune true
查看 git config 文档 以获取所有 git config
可以执行的操作(非常长)。
1Git 文档通常将这些称为 remote-tracking branch 名称,但我认为如果我们在此处留下单词 branch,它的含义最终会更清晰。
2Git 的所有名称 - 分支名称、标记名称、远程跟踪名称和其他类似的名称 - 都驻留在 命名空间 中,并具有更长的、完全限定的名称,以使它们明确。例如,您的 master
分支实际上是 refs/heads/master
;如果您有一个标记 v1.2
,那么实际上是 refs/tags/v1.2
。像 origin/master
这样的远程跟踪名称实际上是 refs/remotes/origin/master
。
当显示这些缩写名称时,Git 通常会削去分支名称的 refs/heads/
部分、标记名称的 refs/tags/
部分和远程跟踪名称的 refs/remotes/
部分。出于某种原因,git branch -a
只在显示远程跟踪名称时削去了 refs/
部分,即使 git branch -r
削去了远程跟踪名称的 refs/remotes/
部分。(我不清楚这是为什么。)
由于这里涉及到第二个 Git,您也可以让您的 Git 立即调用它,列出所有分支名称,并让您的 Git 打印这些名称。 git ls-remote
命令正是这样做的:
git ls-remote origin
使用git ls-remote
命令调用位于origin
的Git,让其列出分支、标签和其他名称,并打印所有这些信息。它不会更新任何远程跟踪名称:这留给git fetch
和git remote update
完成。
git remote show
命令也可以调用其他Git并直接获取信息并显示。有时候它会这样做,有时候则不会。虽然这是有文档说明的,但解释并不太清楚;请参阅git remote文档以获取详细信息。
git branch -r
显示您本地的远程跟踪名称。因为这完全是本地的,所以很快速。但是可能已经过期。
git fetch
更新您本地的远程跟踪名称; 添加 -p
或 --prune
以清理掉已过期的条目,或设置 fetch.prune
为 true。它相对较慢,因为它还添加了他们拥有而您没有的任何新提交,但之后,您的远程跟踪名称将很快使用。
git remote update
基本上与 git fetch
执行相同的任务。由于 git fetch
更短,因此我建议使用 git fetch
。
git ls-remote
调用另一个Git并获取其分支名称。虽然有点慢,但如果有新提交,则不像 git fetch
那样慢,因为它只获取名称和相应的哈希ID而不是提交。
git remote show
有时在本地工作,有时调用其他Git。我觉得它的行为有点令人困惑,也不是很有帮助,通常建议避免使用它。# -a = all branches
$ git branch -a
# -r = remote branches
$ git branch -r
git fetch
git fetch
会用远程仓库的内容更新本地仓库。
添加 --prune
将会删除远程已经被删除的分支,但是如果这些分支在本地被检出了,它们将不会被删除。
$ git fetch --all --prune
git remote prune
为了清理远程跟踪分支,即删除对不存在的远程分支的引用,请使用“git remote prune
”命令并指定远程名称。
$ git remote prune <remote name>
--heads
参数,你将得到分支信息。
git ls-remote --heads
git fetch --prune
- fredrik