为什么叫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如何处理“跟踪上游”。
每个“远程”只是一个名字,就像这种情况下的origin
或octopress
。 他们的目的是logging你的git fetch
或git pull
更新地点的完整URL。 当你使用git fetch remote ,
1 git会去那个远程(使用保存的URL)并且带来相应的一组更新。 它还使用“远程分支” logging更新。
一个“远程分支”就是一个“远程”上最后看到的分支的logging。 每个远程本身就是一个git仓库,所以它有分支。 远程“起源”上的分支logging在remotes/origin/
下的本地存储库中。 你显示的文字说有一个名为source
分支,在octopress
上分支名为2.1
, linklog
等等。
(当然,“正常”或“本地”分支只是您在自己的存储库中创build的分支名称。)
最后,你可以设置一个(本地)分支来“追踪”一个“远程分支”。 一旦本地分支L
被设置为跟踪远程分支R
,git会调用R
的“上游”,并告诉你是否在“上游”和/或“落后”上游(在提交方面)。 本地分支机构和远程分支机构使用相同的名称(远程前缀部分除外)(如source
和origin/source
)是正常的(甚至可以推荐),但实际上并不需要。
在这种情况下,这没有发生。 您有一个本地分支source
跟踪远程分支origin/master
。
你不需要知道git 如何设置一个本地分支来跟踪远程分支的确切机制,但是它们在下面是相关的,所以我将展示它是如何工作的。 我们从您的本地分行名称, source
。 有两个使用这个名字的configuration条目,拼写branch.source.remote
和branch.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.origin
和branch.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.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
是现在错了。
正是在这一点上,“上游”联系打破了,但在1.8.5以上的git版本,git从来没有注意到破碎的设置。 现在你有1.8.5,这是指出这一点。
这涵盖了大部分的问题,但不包括“我需要解决的问题”。 通过做git pull remote branch
(例如git pull origin source
),你可能已经多年来一直在解决这个问题了。 如果你一直这样做,它会继续解决这个问题 – 所以,不,你不需要修复它。 如果你喜欢的话,你可以使用--unset-upstream
去除上游并停止投诉,而不是将本地分支source
标记为任何上游。
上游的目的是使各种操作更方便。 例如,如果上游设置正确, git fetch
和git 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.fetch
下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
说你想做什么,而不是让你自己动手做,所以这是一个“更好的方法”。
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