当涉及到git的高级操作时,我更像是一个新手。我使用博客框架Octopress来维护我的博客。虽然Octopress自2011年以来没有任何开发,但它很好地满足了我的目的,所以到目前为止我还没有想过要改变任何东西。

仅供参考,我的博客托管在Github Pages上。

今天,在工作在一个新的帖子,git状态显示以下消息:

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 commit -m 'message'和git push origin source。

这条信息是什么意思? 有什么东西坏了吗? 如果是,是什么? 我需要修理它吗?

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

更多的细节:

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版本:远程跟踪分支源/主曾经存在,但现在不存在了,所以本地分支源正在跟踪一些不存在的东西,这充其量是可疑的——这意味着不同的Git特性无法为您做任何事情——Git会警告您。在没有“上游跟踪”功能的情况下,您已经运行得很好了,因此是否进行任何更改取决于您。

关于上游设置的另一个例子,请参见为什么我必须“git push——set-upstream origin <branch>”?


这个警告在Git中是新出现的,首次出现在Git 1.8.5中。发布说明只包含一个简短的项目:

"git branch -v -v"(和"git status")没有区分 不基于任何其他分支的分支,在中的分支 与它的上游分支和配置了 上游分支不再存在。

要描述它的含义,首先需要了解“远程”、“远程跟踪分支”以及Git如何处理“跟踪上游”。(远程跟踪分支是一个有严重缺陷的术语——我已经开始使用远程跟踪名称,我认为这是一个轻微的改进。下面,为了与Git文档保持一致,我将使用“远程跟踪分支”。)

每个“远程”只是一个名字,就像在这种情况下的起源或章鱼一样。它们的目的是记录git获取或提取更新的地方的完整URL。当你使用git获取远程,1 git去到那个远程(使用保存的URL),并带来适当的更新集。它还使用“远程跟踪分支”记录更新。

“远程跟踪分支”(或远程跟踪名称)只是在某个“远程”上最后看到的分支名称的记录。每个远程本身就是一个Git存储库,因此它有分支。远程“origin”上的分支记录在remotes/origin/下的本地存储库中。您显示的文本显示,在origin上有一个名为source的分支,在octopress上有一个名为2.1、linklog等分支。

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

最后,您可以设置一个(本地)分支来“跟踪”一个“远程跟踪分支”。一旦本地分支L被设置为跟踪远程跟踪分支R, Git将把R称为它的“上游”,并告诉您是“领先”还是“落后”上游(就提交而言)。本地分支和远程跟踪分支使用相同的名称(除了远程前缀部分)是正常的(甚至是推荐的),例如source和origin/source,但实际上这并不是必要的。

在这种情况下,这是不可能的。您有一个本地分支源跟踪一个远程跟踪分支源/主。

您不需要知道Git如何设置本地分支来跟踪远程分支的确切机制,但它们与下面的内容相关,因此我将展示这是如何工作的。我们从您的本地分支机构名称开始。有两个配置项使用这个名称,拼写为branch.source.remote和branch.source.merge。从您显示的输出中,很明显这两个都已设置,因此如果运行给定的命令,您将看到以下内容:

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

把这些放在一起,2这会告诉Git你的分支源跟踪你的“远程跟踪分支”,origin/master。

但是现在看一下git branch -a的输出,它显示了存储库中所有本地和远程跟踪分支的名称。远程跟踪名称列在remotes/…并且没有remotes/origin/master。大概曾经有过,但现在没了。

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

不过,你想要的似乎很可能是从追踪起源/主人转向追踪其他东西:可能是起源/来源,但也可能是章鱼/名字中的一个。

你可以用git分支——set-up - stream-to来实现这一点,例如:

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

(假设您仍然在分支“source”上,并且该源/源是您想要的上游—但是,如果有的话,我无法告诉您真正想要的是哪一个)。

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

I think the way you got here is that when you first did a git clone, the thing you cloned-from had a branch master. You also had a branch master, which was set to track origin/master (this is a normal, standard setup for git). This meant you had branch.master.remote and branch.master.merge set, to origin and refs/heads/master. But then your origin remote changed its name from master to source. To match, I believe you also changed your local name from master to source. This changed the names of your settings, from branch.master.remote to branch.source.remote and from branch.master.merge to branch.source.merge ... but it left the old values, so branch.source.merge was now wrong.

就在这时,“上游”链接中断了,但在1.8.5以上的Git版本中,Git从未注意到这个中断的设置。现在你有了1.8.5,它指出了这个。


这涵盖了大部分问题,但不包括“我需要修理它吗”这个问题。很可能你已经在这个问题周围工作了好几年了,通过做git pull远程分支(例如,git pull origin source)。如果你继续这样做,它将继续围绕这个问题工作,所以,不,你不需要修复它。如果您愿意,您可以使用——unset-upstream来删除上游并停止投诉,并且根本不将本地分支源标记为具有任何上游。

有上游的意义在于使各种操作更加方便。例如,如果上游设置正确,git fetch之后的git merge通常会“做正确的事情”,并且git fetch之后的git状态会告诉你你的repo是否与上游的匹配,对于那个分支。

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


1git pull使用git fetch,从git 1.8.4开始,这(终于!)也更新了“远程跟踪分支”信息。在旧版本的Git中,更新不会通过Git pull记录在远程跟踪分支中,只能通过Git fetch记录。因为你的Git至少是1.8.5版本,所以这对你来说不是问题。

好的,这加上我故意忽略的在remote.origin.fetch下找到的配置行。Git必须映射“merge”名称,以确定远程分支的完整本地名称是refs/remotes/origin/master。映射几乎总是像这样工作,所以可以预测master到origin/master。

3或者,使用git配置。如果你只想将上游设置为origin/source,唯一需要更改的部分是branch.source。合并,git配置branch.source.merge refs/heads/source 会这么做的。但是——set-upstream-表示你想要做什么,而不是让你自己手动去做,所以这是一个“更好的方法”。


Actually torek told you already how to use the tools much better than I would be able to do. However, in this case I think it is important to point out something peculiar if you follow the guidelines at http://octopress.org/docs/deploying/github/. Namely, you will have multiple github repositories in your setup. First of all the one with all the source code for your website in say the directory $WEBSITE, and then the one with only the static generated files residing in $WEBSITE/_deploy. The funny thing of the setup is that there is a .gitignore file in the $WEBSITE directory so that this setup actually works.

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

cd _deploy

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

在.git/config中,你通常需要找到这样的东西:

[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涉及不同的存储库。


torek的答案可能是完美的,但我只是想提一个与原始问题中描述的不同,但可能出现相同错误的情况(因为它可能会帮助其他有类似问题的人):

我已经在我的一个服务器上使用git init -bare创建了一个空(新)repo。然后我将git克隆到我PC上的本地工作区。

在本地回购上提交一个版本后,我在调用git状态后得到了这个错误。

根据torek的回答,我明白发生了什么,第一次提交本地工作目录repo创建了“主”分支。但是在远程回购(在服务器上)从来没有任何东西,所以甚至没有一个“主”(remotes/origin/master)分支。

在运行git从本地repo推送origin master后,远程repo终于有了一个主分支。这阻止了错误的出现。

所以总结一下——一个新的远程回购可能会得到这样一个零提交的错误,因为它没有分支,包括“master”。


这可能会解决你的问题。

在做了更改之后,你可以提交它,然后

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

希望这对你有用。

谢谢


对我来说,.git/refs/origin/master已经被损坏了。

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

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

我遇到过两次这个问题,而且总是由我本地分支的git缓存文件损坏引起的。我通过将缺失的提交散列写入该文件来修复它。我从服务器上获得了正确的提交散列,并在本地运行了以下命令:

cat .git/refs/remotes/origin/feature/mybranch \
echo 1edf9668426de67ab764af138a98342787dc87fe \
>> .git/refs/remotes/origin/feature/mybranch

问题:你的分支基于“起源/主”,但上游已经没有了。

解决方案:git分支——unset-upstream


使用以下命令删除本地分支

git branch -d branch_name

你也可以

git branch -D branch_name 

基本上强制删除(即使本地未合并到源)


这是最简单的解决方案,你只要把git分支——unset-upstream,如果你在git push之前输入git状态,在commit之后你会看到你的分支是基于'origin/main'的,但是upstream已经没有了。(使用“git branch——unset-upstream”来修复)希望能有所帮助

图片说明