TL;DR版本:远程跟踪分支
origin/master
曾经存在,但现在不存在了,因此本地分支
source
正在跟踪一个不存在的东西,这至少是可疑的——这意味着不同的Git功能无法为您做任何事情——Git正在警告您。 没有必要让"上游跟踪"功能按预期工作,您可以自行决定是否更改任何内容。
关于上游设置的另一种方法,请参见
为什么我需要“git push --set-upstream origin ”?
这个警告是 Git 中的新功能,首次出现在 Git 1.8.5 中。发布说明仅包含一个短点项:
- "git branch -v -v"(以及 "git status")没有区分一个不基于任何其他分支的分支、与其上游分支同步的分支和配置了不存在的上游分支的分支。
要描述它的意思,您首先需要了解 "远程"、"远程跟踪分支" 以及 Git 如何处理 "跟踪上游"。("远程跟踪分支" 是一个非常有缺陷的术语——我已经开始使用 "远程跟踪名称" 来代替,我认为这是一个略微的改进。然而,在下面,我将使用 "远程跟踪分支" 来保持与 Git 文档的一致性。)
每个“远程”只是一个名称,比如在这种情况下的
origin
或
octopress
。它们的目的是记录像从中获取
git fetch
或
git pull
更新的完整URL这样的事情。当您使用
git fetch remote,
1 Git会使用保存的URL到达该远程并带来适当的更新集。它还使用“远程跟踪分支”记录更新。
“远程跟踪分支”(或远程跟踪名称)只是一条记录某个“远程”上最后看到的分支名称。每个远程本身都是一个Git存储库,因此它具有分支。在本地存储库中,记录了远程“origin”的分支为remotes/origin/
。您显示的文本说明在origin
上有一个名为source
的分支,在octopress
上有名为2.1
、linklog
等的分支。
(当然,“正常”或“本地”分支只是您在自己的存储库中创建的分支名称。)
最后,你可以设置一个(本地)分支来“追踪”一个“远程跟踪分支”。一旦本地分支
L
被设置为追踪远程跟踪分支
R
,Git将称
R
为其“上游”,并告诉你当前分支相对于上游(提交方面)是“超前”还是“落后”。通常情况下(甚至推荐),本地分支和远程跟踪分支使用相同的名称(除了远程前缀部分),例如
source
和
origin/source
,但这并非必需。
在这种情况下,这种情况并没有发生。你有一个本地分支
source
跟踪着一个远程跟踪分支
origin/master
。
你不需要知道Git如何设置本地分支来跟踪远程分支的具体机制,但在下面的内容中它们是相关的,所以我会展示一下它是如何工作的。我们从你的本地分支名称source
开始。使用这个名称有两个配置条目,拼写为branch.source.remote
和branch.source.merge
。从你展示的输出中可以清楚地看到,这两个都已经设置好了,因此如果你运行给定的命令,你将会看到以下内容:
$ git config --get branch.source.remote
origin
$ git config --get branch.source.merge
refs/heads/master
综合起来,这告诉Git你的分支source
跟踪你的“远程跟踪分支”origin/master
。
但是现在看一下git branch -a
的输出,它显示了存储库中所有本地和远程跟踪分支的名称。远程跟踪名称列在remotes/
下面...而且没有remotes/origin/master
。可能曾经有过,但现在已经消失了。
Git告诉你可以使用--unset-upstream
删除跟踪信息。这将清除branch.source.origin
和branch.source.merge
,并停止警告。
不过,你想要的很可能是从跟踪origin/master
切换到跟踪其他东西:可能是origin/source
,但也可能是octopress/
之一。
你可以使用git branch --set-upstream-to
来实现,例如:
$ git branch --set-upstream-to=origin/source
假设您仍在“source”分支上,并且
origin/source
是您想要的上游 - 如果有任何一个,我无法告诉您实际想要哪个。请参见
如何使现有的Git分支跟踪远程分支?。
我觉得您到达这里的方式是,当您第一次执行
git clone
时,克隆源有一个
master
分支。您也有一个
master
分支,它被设置为跟踪
origin/master
(这是Git的正常标准设置)。这意味着您已经设置了
branch.master.remote
和
branch.master.merge
,分别为
origin
和
refs/heads/master
。但是,然后您的
origin
远程更改其名称从
master
到
source
。为了匹配,我相信您还将本地名称从
master
更改为
source
。这将更改您的设置名称,从
branch.master.remote
更改为
branch.source.remote
,从
branch.master.merge
更改为
branch.source.merge
,但是保留了旧值,所以
branch.source.merge
现在是错误的。
在这个时候,“上游”链接断开了,但是在 Git 1.8.5 之前的版本中,Git 没有注意到这个断开的设置。现在你有了 1.8.5,它会指出这一点。
这基本上回答了大部分问题,但没有回答“我需要修复它吗”的问题。你可能已经绕过了这个问题很多年,通过执行
git pull remote branch
(例如,
git pull origin source
)。如果你一直这样做,它将继续解决问题,所以不,你不需要修复它。如果你愿意,你可以使用
--unset-upstream
来删除上游并停止投诉,并且不需要将本地分支
source
标记为具有
任何上游。
设置上游的目的是使各种操作更加方便。例如,如果正确设置了上游,接下来执行
git fetch
和
git merge
通常会“做正确的事情”,并且在
git fetch
后执行
git status
将告诉您您的repo是否与上游分支匹配。
如果你想要这种便利,重新设置上游即可。
1git pull
使用git fetch
,从Git 1.8.4开始,这也更新了“远程跟踪分支”的信息。在旧版本的Git中,使用git pull
没有将更新记录在远程跟踪分支中,只有使用git fetch
才行。由于您的Git必须至少是1.8.5版本,所以这对您来说不是问题。
2好吧,还有一行配置我故意忽略了,它可以在remote.origin.fetch
下找到。Git必须映射“合并”名称以确定远程分支的完整本地名称为refs/remotes/origin/master
。虽然映射几乎总是像这样工作,但它预测到master
会转到origin/master
。
3 或者,使用 git config
。如果您只想将上游设置为 origin/source
,那么唯一需要更改的部分是 branch.source.merge
,而 git config branch.source.merge refs/heads/source
就可以做到这一点。但是,--set-upstream-to
表示您想要完成的任务,而不是让您手动去完成,这是一种“更好的方法”。
<commit_id> (HEAD->master, m/master, origin/master, local-branch)
,我很确定m/master
是虚假的,因为当列出所有分支时,它显示为remotes/m/master -> origin/local-branch
。解决方法仍然有效,但实际上解决问题会更好。 - taranakiremotes/m/master
(如git branch -a
所示)表示这是一个远程跟踪名称。它不是分支名称,因此没有上游设置。如果显示为remotes/m/master -> origin/local-branch
,那么这个特定的远程跟踪名称是一个符号引用。有人使用git symbolic-ref
创建了它。您可以使用git branch -r -d m/master
删除该符号引用。 - torek