为什么调用git branch --unset-upstream进行修复?


160

关于git中的高级操作,我还是一个新手。我使用博客框架Octopress维护我的博客。尽管Octopress自2011年以来未进行任何开发,但它很好地满足了我的目的,因此到目前为止我还没有想到要进行任何更改。

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

今天,在撰写新帖子时,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 commit -m 'message'git push origin source

  • 该消息是什么意思?
  • 东西坏了吗?
  • 如果是,那是什么?
  • 我需要修复它吗?

如果可能的话,请指向pdf / web文章,我可以阅读该文章并在以后理解。

更多细节:

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

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

Answers:


196

TL; DR版本:远程跟踪分支origin/master曾经存在,但现在不存在,因此本地分支source正在跟踪不存在的事物,这充其量是可疑的-这意味着不同的Git功能无法为您做任何事情- Git正在警告您。您一直都很好,而没有按预期工作“上游跟踪”功能,因此,是否更改任何内容取决于您。

有关上游设置的其他信息,请参见为什么必须“ git push --set-upstream origin <branch>”?


该警告是Git中的新事物,在Git 1.8.5中首先出现。发行说明仅包含一个简短的项目符号:

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

要描述其含义,您首先需要了解“远程”,“远程跟踪分支”以及Git如何处理“跟踪上游”。(远程跟踪分支是一个非常有缺陷的术语-我开始改用远程跟踪名称,我认为这是一个小改进。不过,在下面,我将使用“远程跟踪分支”来确保与Git文档的一致性。 )

每个“远程”仅是一个名称,如originoctopress在这种情况下。它们的目的是记录诸如您git fetch或要git pull更新的地方的完整URL之类的内容。当您使用1时, Git会转到该遥控器(使用保存的URL)并带来适当的更新集。它还使用“远程跟踪分支” 记录更新。git fetch remote,

“远程跟踪分支”(或远程跟踪名称)只是在某些“远程”上最后一次看到的分支名称的记录。每个远程本身就是一个Git存储库,因此它具有分支。远程“来源”上的分支记录在本地存储库下remotes/origin/。你表现的文中说,有一个名为分支sourceorigin,和树枝命名2.1linklog等上octopress

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

最后,您可以设置一个(本地)分支来“跟踪”“远程跟踪分支”。一旦本地分支L设置为跟踪远程跟踪分支R,Git就会将R其称为“上游”,并告诉您(在提交方面)您是否在上游“之前”和/或“后面”。本地分支和远程跟踪分支使用相同的名称(远程前缀部分除外)是正常的(甚至是推荐的),例如sourceorigin/source,但这实际上不是必需的。

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

您不需要了解Git 如何设置本地分支来跟踪远程分支的确切机制,但是它们在下面是相关的,因此,我将展示它的工作原理。我们以您当地的分支机构名称开头source。有两个使用此名称的配置条目,spelled 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-to3执行此操作,例如:

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

(假设您仍在分支“源”上,而这origin/source是您想要的上游,尽管如此,我无法告诉您实际上想要的是哪一个)。

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

我认为您到达这里的方式是,当您第一次执行a时git clone,从中克隆的东西有了一个分支master。您还具有一个branch master,该分支设置为可跟踪origin/master(这是git的常规标准设置)。这意味着你有branch.master.remotebranch.master.merge设置,以originrefs/heads/master。但是随后您的origin遥控器将其名称从更改mastersource。为了匹配,我相信您也将自己的本地名称从更改mastersource。这将您的设置名称branch.master.remote更改为branch.source.remote,从... 更改branch.master.mergebranch.source.merge...,但是它保留了旧,因此branch.source.merge现在是错误的。

正是在这一点上,“上游”链接断开了,但是在1.8.5之前的Git版本中,Git从未注意到断开的设置。现在您有了1.8.5,它指出了这一点。


这涵盖了大多数问题,但没有涵盖“我需要解决”这个问题。通过执行(例如),您可能已经在坏处工作了多年了。如果您继续这样做,它将继续解决问题,因此,不需要,您无需修复它。如果愿意,您可以使用删除上游并停止投诉,而不必将本地分支标记为完全没有上游。git pull remote branchgit pull origin source--unset-upstreamsource

上游的目的是使各种操作更加方便。例如,git fetch其次是git merge一般“做正确的事情”,如果上游设置正确,并且git status之后git fetch会告诉你你的回购是否匹配上游之一,该分支。

如果需要方便,请重新设置上游。


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。不过,映射几乎总是像这样工作,因此可以预料masterorigin/master

3或者,使用git config。如果您只想将上游设置origin/source为唯一需要更改的部分branch.source.mergegit config branch.source.merge refs/heads/source 那就可以了。但是,--set-upstream-to什么你想要做的,而不是让你去自己做手工,所以这是一个“更好的方式”。


3
+1表示“如果愿意,可以使用--unset-upstream将本地分支标记为根本没有上游。”
BeatriceThalo

157

torek的答案可能是完美的,但我只是想在记录中提及另一种情况,该情况与原始问题中描述的情况不同,但可能会出现相同的错误(因为这可能会帮助其他遇到类似问题的人):

git init --bare在其中一台服务器上创建了一个空的(新的)存储库。然后,将git clone其保存到PC上的本地工作区。

在本地存储库中提交单个版本后,调用时出现了该错误git status

遵循torek的回答,我知道发生的事情是在本地工作目录存储库上的第一次提交创建了“ master”分支。但是在远程仓库(在服务器上)上什么都没有,所以甚至没有“ master”(远程/原始/ master)分支。

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

因此可以得出结论-对于零提交的新的远程回购,由于它没有分支(包括“ master”),因此可能会收到这样的错误。


6
当前,此错误消息是nr 1的结果On branch source Your branch is based on 'origin/master', but the upstream is gone. (use "git branch --unset-upstream" to fixup),虽然主观的,但这很可能是由于克隆一个空的存储库而引起的,该存储库太好了,可以在此处找到替代答案。
贝拉

2
我想这就是为什么它始终是一个好主意,初始化文件README.md新的存储库,即使它是一个空文件
艾哈迈德·侯赛因

8

这可能会解决您的问题。

完成更改后,您可以提交它,然后

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

希望对你有效。

谢谢


1
这确实有帮助-原因在我的答案中得到了详细说明(简而言之-这会在远程回购中创建丢失的master分支)。
ElazarR '16

7

对我来说,.git/refs/origin/master已经腐败了。

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

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

0

实际上,torek已经告诉您如何比我能更好地使用这些工具。但是,在这种情况下,如果您遵循http://octopress.org/docs/deploying/github/上的指南,我认为有必要指出一些特殊的东西,这一点很重要。即,您的设置中将有多个github存储库。首先将目录中包含您网站的所有源代码$WEBSITE,然后将目录中仅包含静态生成的文件放在目录中$WEBSITE/_deploy。该设置的有趣之处在于,目录中有一个.gitignore文件,$WEBSITE因此该设置可以实际运行。

足够的介绍。在这种情况下,错误也可能来自中的存储库_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:可能值得将外壳(例如zsh带有git插件)与以后使用的东西隔离。它将立即表明与_deploy另一个存储库有关。


0

我有两次这个问题,它总是由本地分支上的git缓存文件损坏引起的。我通过将丢失的提交哈希写入该文件来解决该问题。我从服务器获得了正确的提交哈希,并在本地运行了以下命令:

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

0

问题:您的分支基于“来源/主”,但上游已消失。

解决方案:git branch --unset-upstream


3
欢迎来到stackoverflow。问题不是关于如何解决该错误,他想知道为什么会引发此错误,以及是否应该对此采取措施。请在您的答案中解决。
cronoik

0

通过以下命令删除本地分支

git branch -d branch_name

你也可以

git branch -D branch_name 

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.