如何在Git中列出所有远程现有分支?

24

我尝试过使用git remote -r命令查看所有远程存在的分支,但我发现结果包括那些已从远程删除的分支。

有没有办法过滤掉这些“僵尸”分支呢?


3
这个回答是否解答了你的问题?删除不再存在于远程的跟踪分支 - mkrieger1
4
git fetch --prune - fredrik
1
请查看ls-remote文档。 - Lasse V. Karlsen
这明显是一个重复的问题,为什么它很久以前就没有被关闭?我们不应该一遍又一遍地回答相同的初学者问题。 - Peter Mortensen
3个回答

30

这个问题有几个可能的潜在含义,因此它有几个可能的答案。关键问题是至少涉及两个不同的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 fetchgit 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。我觉得它的行为有点令人困惑,也不是很有帮助,通常建议避免使用它。

10

列出分支:

# -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>

3
如果你在列出远程引用时指定了--heads参数,你将得到分支信息。 git ls-remote --heads

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接