繁体   English   中英

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

[英]git branch -r shows different remote shared repo in different local working directory

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

现在有两个分支, masterv0 文件夹A和B现在位于分支v0 在AI上删除了远程仓库上的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对远程仓库有不同的看法?

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

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

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

文档

从Jan的镜像官方git fetch docs

 -p --prune 

获取后,删除远程不再存在的任何远程跟踪引用。 如果仅由于默认标记自动跟踪或由于--tags选项而提取标记,则不对其进行修剪。 但是,如果由于显式refspec(在命令行或远程配置中,例如,如果使用--mirror选项克隆远程)而--mirror ,则它们也会受到修剪。

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

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


在任何情况下,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删除遥控器上现在缺少的v0本地origin/v0副本,则应该在git fetch命令中添加--prune选项。 2这告诉你当地的git删除本地origin/ whatever ,只要遥控器上的whatever已经消失。 否则,你当地的git会保留它。

为什么git push --delete删除它,当git fetch没有--prune保留它? 对于编写git本身的人来说,这是一个问题。 3


1默认情况下,如果您没有设置任何内容来覆盖默认值,则运行git merge 由于git rebase可能是一个更好的默认情况下,有很多的方式,使pull使用rebase

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

34当然:似乎如果你,运行git push的用户,你说要从远程删除分支,你可能不会特别想保留你的分支的本地副本一旦你已经成功删除了他们的分支。 但这只是猜测。

4 我也可以从邪恶的深处召唤灵魂 ,但他们从未出现过。 :-)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM