为什么叫git branch –unset-upstream修正?

对于git中的高级操作,我更喜欢新手。 我使用博客框架Octopress维护我的博客 。 尽pipe自2011年以来Octopress并没有得到任何发展,但它对我的目的很有帮助,所以我没有想到改变目前的情况。

仅供参考,我的博客托pipe在Github页面上。

今天,在一个新post的工作, git status显示以下消息:

 On branch source Your branch is based on 'origin/master', but the upstream is gone. (use "git branch --unset-upstream" to fixup) 

所有随后的命令(如git add .都会重复相同的消息git add .git commit -m 'message'git push origin source

  • 这个消息是什么意思?
  • 有什么东西坏了?
  • 如果是,什么?
  • 我需要修复吗?

如果可能的话,请给我一个PDF /networking文章,我可以在这里阅读并理解它的未来。

更多细节:

 bash-3.2$ git branch -a * source remotes/octopress/2.1 remotes/octopress/HEAD -> octopress/master remotes/octopress/gh-pages remotes/octopress/linklog remotes/octopress/master remotes/octopress/refactor_with_tests remotes/octopress/rubygemcli remotes/octopress/site remotes/origin/source 

请让我知道是否需要更多的信息。 谢谢。

TL; DR版本:远程分支的origin/master曾经存在,但现在不是,所以本地分支source是跟踪不存在的东西,这是最好的可疑 – 这意味着一个不同的gitfunction是无法为你做任何事情和git警告你。 如果没有“上游跟踪”function,你一直相处得很好,因此是否要改变任何东西都取决于你。


这个警告在git中是一个新东西,首先出现在git 1.8.5中。 发行说明仅包含一个关于它的简短的项目符号:

  • “git branch -v -v”(和“git status”)没有区分不是基于任何其他分支的分支,与其上游分支同步的分支以及configuration有上游的分支分支不再存在。

为了描述它的含义,首先需要了解“远程”,“远程分支”以及git如何处理“跟踪上游”。

每个“远程”只是一个名字,就像这种情况下的originoctopress 。 他们的目的是logging你的git fetchgit pull更新地点的完整URL。 当你使用git fetch remote , 1 git会去那个远程(使用保存的URL)并且带来相应的一组更新。 它还使用“远程分支” logging更新。

一个“远程分支”就是一个“远程”上最后看到的分支的logging。 每个远程本身就是一个git仓库,所以它有分支。 远程“起源”上的分支logging在remotes/origin/下的本地存储库中。 你显示的文字说有一个名为source分支,在octopress上分支名为2.1linklog等等。

(当然,“正常”或“本地”分支只是您在自己的存储库中创build的分支名称。)

最后,你可以设置一个(本地)分支来“追踪”一个“远程分支”。 一旦本地分支L被设置为跟踪远程分支R ,git会调用R的“上游”,并告诉你是否在“上游”和/或“落后”上游(在提交方面)。 本地分支机构和远程分支机构使用相同的名称(远程前缀部分除外)(如sourceorigin/source )是正常的(甚至可以推荐),但实际上并不需要。

在这种情况下,这没有发生。 您有一个本地分支source跟踪远程分支origin/master

你不需要知道git 如何设置一个本地分支来跟踪远程分支的确切机制,但是它们在下面是相关的,所以我将展示它是如何工作的。 我们从您的本地分行名称, source 。 有两个使用这个名字的configuration条目,拼写branch.source.remotebranch.source.merge 。 从显示的输出中可以明显看出,这些都是设置的,所以如果你运行给定的命令,你会看到以下内容:

 $ git config --get branch.source.remote origin $ git config --get branch.source.merge refs/heads/master 

把它们放在一起, 2告诉git你的分支source跟踪你的“远程分支”, origin/master

但现在看看git branch -a的输出,它显示了你的仓库中的所有本地和远程分支。 远程分支被列在remotes/ …并且没有remotes/origin/master 。 可能有一次,但现在已经消失了。

Git告诉你可以使用--unset-upstream 删除跟踪信息。 这将清除branch.source.originbranch.source.merge ,并停止警告。

看起来相当可能的是,你想要的是从跟踪origin/master 切换到跟踪别的东西:可能是origin/source ,但也许是octopress/名称之一。

你可以用git branch --set-upstream-to来做到这一点,例如:

 $ git branch --set-upstream-to=origin/source 

(假设你仍然在分支“来源”,而这个origin/source是你想要的上游),但是我没有办法告诉哪一个,如果有的话,你真的想要的)。

(另请参见如何让现有的Git分支跟踪远程分支? )

我认为你在这里的方式是,当你第一次做一个git clone ,你克隆的东西有一个分支master 。 你也有一个分支master ,它被设置为跟踪origin/master (这是一个正常的,标准的git设置)。 这意味着你有branch.master.remotebranch.master.merge设置, originrefs/heads/master 。 但是,那么你的origin远程改变了名字从mastersource 。 为了配合,我相信你也把你的本地名字从master变成了source 。 这改变了你的设置名称 ,从branch.master.remotebranch.source.remote ,从branch.master.mergebranch.source.merge ,但是它留下了旧的 ,所以branch.source.merge是现在错了。

正是在这一点上,“上游”联系打破了,但在1.8.5以上的git版本,git从来没有注意到破碎的设置。 现在你有1.8.5,这是指出这一点。


这涵盖了大部分的问题,但不包括“我需要解决的问题”。 通过做git pull remote branch (例如git pull origin source ),你可能已经多年来一直在解决这个问题了。 如果你一直这样做,它会继续解决这个问题 – 所以,不,你不需要修复它。 如果你喜欢的话,你可以使用--unset-upstream去除上游并停止投诉,而不是将本地分支source标记为任何上游。

上游的目的是使各种操作更方便。 例如,如果上游设置正确, git fetchgit merge通常会“做正确的事情”, git fetch之后的git merge git status会告诉你你的repo是否匹配上游的那个分支。

如果你想方便,重新设置上游。


1 git pull使用git fetch ,而从git 1.8.4开始,这个(最后!)也更新了“remote branch”信息。 在较旧版本的git中,更新没有使用git pull在远程分支中logging,只能使用git fetch 。 既然你的git必须至less是1.8.5版,这对你来说不是问题。

2那么,这加上一个configuration线,我故意忽略,是在remote.origin.fetchremote.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说你想做什么,而不是让你自己动手做,所以这是一个“更好的方法”。

torek的回答可能是完美的,但我只是想提供另外一个与原问题中描述的不同的案例,但是同样的错误可能会出现(因为它可能会帮助其他类似的问题):

我已经创build了一个空的(新)回购使用git init --bare在我的一台服务器上。 然后我把它git clone到我的电脑本地工作区。

在本地回购单上提交单一版本后,我调用git status后出现错误。

在torek的回答之后,我了解到发生了什么事是第一次提交本地工作目录repo创build了“master”分支。 但在远程回购(在服务器上)从来没有任何东西,所以甚至没有一个“主”(远程/起源/主)分支。

从本地仓库运行git push origin master后,远程仓库终于有了一个master分支。 这阻止了出现的错误。

所以得出结论 – 由于没有分支(包括“主”),可能会出现这样的错误,因为它没有提交,因此提交了一个零提交的新远程仓库。

这可能会解决你的问题。

做完变更后,你可以提交它,然后

 git remote add origin https://(address of your repo) it can be https or ssh then git push -u origin master 

希望对你有效。

谢谢

事实上,torek已经告诉过你如何使用这些工具比我能做得更好。 然而,在这种情况下,我认为如果你遵循http://octopress.org/docs/deploying/github/上的指导原则,指出一些特殊的东西是非常重要的。; 也就是说,您的设置中将有多个github存储库 。 首先为您的网站提供所有源代码,例如$WEBSITE目录,然后是只有静态生成的文件(位于$WEBSITE/_deploy 。 有趣的是,在$WEBSITE目录中有一个.gitignore文件,所以这个设置实际上是可行的。

足够的介绍。 在这种情况下,错误也可能来自_deploy的存储库。

 cd _deploy git branch -a * master remotes/origin/master remotes/origin/source 

.git/config您通常需要find如下所示的内容:

 [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] url = git@github.com:yourname/yourname.github.io.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master 

但在你的情况下,分公司没有一个远程。

 [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] url = git@github.com:yourname/yourname.github.io.git fetch = +refs/heads/*:refs/remotes/origin/* 

你可以通过以下方式解决:

 cd _deploy git branch --set-upstream-to=origin/master 

所以,一切都如同torek告诉你的,但重要的是要指出,这可能与_deploy目录有关,而不是网站的根目录。

PS:用git插件等一个shell如zsh可能是值得的,以后不要被这个东西咬了。 它会立即显示_deploy涉及一个不同的存储库。

对我而言, .git/refs/origin/master已经损坏了。

我做了以下,这为我解决了这个问题。

 rm .git/refs/remotes/origin/master git fetch git branch --set-upstream-to=origin/master