git branch -r在不同的本地工作目录中显示不同的远程共享仓库

时间:2015-10-18 00:35:10

标签: git git-branch git-pull git-fetch

我创建了一个共享仓库,然后将其克隆到两个文件夹(A和B)中。全部都在同一台电脑上。

现在有两个分支,masterv0。文件夹A和B现在位于分支v0中。在A上我删除了远程仓库上的v0分支。

$ git push origin --delete v0
To file:///home/nanger/github/shared1.git
 - [deleted]         v0

然后我尝试在A和B上(在分支v0中)拉远程仓库:

现在,我看到了

在A:

$ git pull
Already up-to-date.

$ git branch -r
origin/master

$ git branch
* master
v0

在B:

$ git pull
Already up-to-date

$ git branch -r
origin/HEAD -> origin/master
origin/master
origin/v0

$ git branch
* master
v0

为什么A和B对远程仓库有不同的看法?

3 个答案:

答案 0 :(得分:2)

git pull不会删除正在跟踪遥控器上不再存在的远程分支的本地远程跟踪分支,例如origin/v0

如果要从本地存储库中删除过时的远程跟踪分支,则需要使用

git fetch <remote> --prune
# Or shorter
git fetch <remote> -p

文档

从Jan的官方镜像git fetch docs

-p
--prune
     

获取后,删除遥控器上不再存在的所有远程跟踪引用。标签不受修剪,如果他们   仅由于默认标记自动跟踪或由于a而被提取   --tags选项。但是,如果由于显式refspec(在命令行或远程配置中,为...)提取标记   例如,如果使用--mirror选项克隆了远程,那么它们   也需要修剪。

如果您想要更详细地解释Git中不同类型的分支(本地,远程和远程跟踪)以及如何删除它们,您可以在我对{{3}的回答中阅读所有这些分支。 }。

答案 1 :(得分:2)

为什么你会期望它们是一样的? (这是一个真正的问题;我可以想出一些理由来预期。显然,他们相同,所以这些原因一定是错的。你可能会想出一套不同的“可能的理由是期望它们与我相同”,所以这对于思考为什么你期望它们是相同的是一个有用的练习。)

在任何情况下,git都不太关心任何其他存储库(在同一台计算机或不同的计算机上)中的内容。它一次只能在一个存储库上工作,并且只关心那个存储库中的内容。

此处还需要注意的是git pull是一个执行两项操作的脚本:首先,它运行git fetch,这是与其他git联系的实际命令(通常是但是不一定,在其他一些计算机上)找出“他们拥有的你没有”。然后,完成后,如果需要,git pull会运行git mergegit rebase 1

“其他git”被称为“遥控器”,对于典型的克隆,只有一个遥控器origin

git push命令还与(或)“远程”对话 - 再次,通常,但不一定,在另一台计算机上 - 并询问远程,这是另一个git存储库,更新其(遥控器)本地分支。

我们现在需要一点背景信息。你自己的git尝试使用“远程跟踪”分支跟踪“遥控器上有什么”。这些分支显示为origin/whatever。同样,这与遥控器无关:远程分支标签的这些副本只是存储在本地。

当你做git push --delete v0时,你让你的git调用另一个git并要求它(另一个git)删除它的v0。它确实删除了它之前的(本地)v0分支 - 然后你的git删除了你的本地副本,你的git称为origin/v0

如果您以后更改为其他克隆,则运行git pull并运行git fetch。这个git fetch调用了另一个git(通常在另一台计算机上,但在这种情况下实际上是在同一台笔记本电脑上)。我将在这里略过一些细节(细节取决于特定的git版本:git 1.8.4左右有一个相当大的变化)并假装你运行git fetch(这避免了需要关心这些细节,实际上并不影响最终结果。)

这一次,你的git fetch调用远程git并询问它现在有什么,而远程列出v0,因为它现在已经从远程。这给你的(本地)git带来了一些问题。一段时间之前,你的本地git从那个远程git获得了v0,现在它已经消失了。你的本地git应该删除它的origin/v0,还是应该保留它?

git程序员在这里选择的答案是,你的git应该保持其origin/v0,以防你使用它的东西。如果您希望您的git fetch删除遥控器上现有origin/v0的本地v0副本,则应添加--prune选项到你的git fetch命令。 2 这会告诉你当地的git,只要遥控器的 origin/whatever 消失,就会移除你的本地whatever。否则,你当地的git会保留它。

为什么git push --delete会在git fetch没有--prune的情况下将其删除?这是人们写git本身的问题。 3

1 默认情况下,如果您没有设置任何内容来覆盖默认值,则运行git merge。由于git rebase可能是更好的默认设置,因此有{em>批次方法可以pull使用rebase

2 您还可以使用git remote prune origingit remote update origin --prune。有一些小的git错误使每个人的行为略有不同。据我所知,它们都是在git 2.0或更高版本中修复的。

3 我当然可以 4 :看来如果你这个运行git push的用户说的话如果要从远程删除分支,在成功删除分支后,您可能不希望保留其分支的本地副本。但这只是猜测。

4 I can call spirits from the vasty deep,但他们从未出现过。 : - )

答案 2 :(得分:-1)

根据您的配置, git pull 可能只会拉动您所在的分支。尝试git fetch,然后git branch -r。