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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21609781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 17:41:50  来源:igfitidea点击:

Why call git branch --unset-upstream to fixup?

gitgit-branchgithub-pages

提问by Jatin Ganhotra

I'm more of a novice when it comes to advanced operations in git. I maintain my blogusing the blogging framework Octopress. Though Octopress is not under any development since 2011, it serves my purpose well and so I haven't thought of changing anything so far.

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

FYI, my blog is hosted on Github Pages.

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

Today, while working on a new post, git statusshowed the following message:

今天,在处理一个新帖子时,git status显示了以下消息:

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

The same message repeated for all the subsequent commands such as git add ., git commit -m 'message'and git push origin source.

对所有后续命令(例如git add .git commit -m 'message'和 )重复相同的消息git push origin source

  • What does the message mean?
  • Is something broken?
  • If yes, what?
  • Do I need to fix it?
  • 消息是什么意思?
  • 东西坏了吗?
  • 如果是,是什么?
  • 我需要修复它吗?

If possible, please point me to a pdf/web article where I can read up on this and understand it for future.

如果可能,请将我指向 pdf/web 文章,在那里我可以阅读并理解它以备将来使用。

More details:

更多细节:

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

Please let me know if more information is needed. Thanks.

如果需要更多信息,请告诉我。谢谢。

回答by torek

TL;DR version: remote-tracking branch origin/masterused to exist, but does not now, so local branch sourceis tracking something that does not exist, which is suspicious at best—it means a different Git feature is unable to do anything for you—and Git is warning you about it. You have been getting along just fine without having the "upstream tracking" feature work as intended, so it's up to you whether to change anything.

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

For another take on upstream settings, see Why do I have to "git push --set-upstream origin <branch>"?

有关上游设置的另一种看法,请参阅为什么我必须“git push --set-upstream origin <branch>”?



This warning is a new thing in Git, appearing first in Git 1.8.5. The release notes contain just one short bullet-item about it:

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

  • "git branch -v -v" (and "git status") did not distinguish among a branch that is not based on any other branch, a branch that is in sync with its upstream branch, and a branch that is configured with an upstream branch that no longer exists.
  • “git branch -v -v”(和“git status”)没有区分不基于任何其他分支的分支、与其上游分支同步的分支以及配置有上游分支的分支不再存在的分支。

To describe what it means, you first need to know about "remotes", "remote-tracking branches", and how Git handles "tracking an upstream". (Remote-tracking branchesis a terribly flawed term—I've started using remote-tracking namesinstead, which I think is a slight improvement. Below, though, I'll use "remote-tracking branch" for consistency with Git documentation.)

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

Each "remote" is simply a name, like originor octopressin this case. Their purpose is to record things like the full URL of the places from which you git fetchor git pullupdates. When you use git fetch remote,1Git goes to that remote (using the saved URL) and brings over the appropriate set of updates. It also recordsthe updates, using "remote-tracking branches".

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

A "remote-tracking branch" (or remote-tracking name) is simply a recording of a branch name as-last-seen on some "remote". Each remote is itself a Git repository, so it has branches. The branches on remote "origin" are recorded in your local repository under remotes/origin/. The text you showed says that there's a branch named sourceon origin, and branches named 2.1, linklog, and so on on octopress.

“远程跟踪分支”(或远程跟踪名称)只是对某个“远程”上最后看到的分支名称的记录。每个远程本身就是一个 Git 存储库,因此它有分支。远程“原点”上的分支记录在本地存储库中的remotes/origin/. 您显示的文本说有一个名为sourceon的分支origin,以及名为2.1, 的分支linklog,依此类推octopress

(A "normal" or "local" branch, of course, is just a branch-name that you have created in your own repository.)

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

Last, you can set up a (local) branch to "track" a "remote-tracking branch". Once local branch Lis set to track remote-tracking branch R, Git will call Rits "upstream" and tell you whether you're "ahead" and/or "behind" the upstream (in terms of commits). It's normal (even recommend-able) for the local branch and remote-tracking branches to use the same name (except for the remote prefix part), like sourceand origin/source, but that's not actually necessary.

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

And in this case, that's not happening. You have a local branch sourcetracking a remote-tracking branch origin/master.

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

You're not supposed to need to know the exact mechanics of howGit sets up a local branch to track a remote one, but they are relevant below, so I'll show how this works. We start with your local branch name, source. There are two configuration entries using this name, spelled branch.source.remoteand branch.source.merge. From the output you showed, it's clear that these are both set, so that you'd see the following if you ran the given commands:

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

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

Putting these together,2this tells Git that your branch sourcetracks your "remote-tracking branch", origin/master.

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

But now look at the output of git branch -a, which shows all the local and remote-tracking branch names in your repository. The remote-tracking names are listed under remotes/... and there is no remotes/origin/master. Presumably there was, at one time, but it's gone now.

但是现在看看 的输出git branch -a,它显示了存储库中的所有本地和远程跟踪分支名称。远程跟踪名称列在remotes/...下,没有remotes/origin/master. 据推测,曾经有过,但现在已经消失了。

Git is telling you that you can removethe tracking information with --unset-upstream. This will clear out both branch.source.originand branch.source.merge, and stop the warning.

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

It seems fairly likely that what you want, though, is to switchfrom tracking origin/master, to tracking something else: probably origin/source, but maybe one of the octopress/names.

但是,您想要的似乎很可能是从跟踪切换origin/master到跟踪其他内容:可能是origin/source,但可能是octopress/名称之一。

You can do this with git branch --set-upstream-to,3e.g.:

您可以使用git branch --set-upstream-to, 3执行此操作,例如:

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

(assuming you're still on branch "source", and that origin/sourceis the upstream you want—there is no way for me to tell which one, if any, you actually want, though).

(假设您仍然在分支“源”上,这origin/source就是您想要的上游 - 但是我无法确定您真正想要哪个,如果有的话)。

(See also How do you make an existing Git branch track a remote branch?)

(另请参阅如何使现有的 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.remoteand branch.master.mergeset, to originand refs/heads/master. But then your originremote changed its name from masterto source. To match, I believe you also changed your local name from masterto source. This changed the namesof your settings, from branch.master.remoteto branch.source.remoteand from branch.master.mergeto branch.source.merge... but it left the old values, so branch.source.mergewas now wrong.

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

It was at this point that the "upstream" linkage broke, but in Git versions older than 1.8.5, Git never noticed the broken setting. Now that you have 1.8.5, it's pointing this out.

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



That covers most of the questions, but not the "do I need to fix it" one. It's likely that you have been working around the broken-ness for years now, by doing git pull remote branch(e.g., git pull origin source). If you keep doing that, it will keep working around the problem—so, no, you don't needto fix it. If you like, you can use --unset-upstreamto remove the upstream and stop the complaints, and not have local branch sourcemarked as having anyupstream at all.

这涵盖了大部分问题,但不包括“我需要修复它吗”的问题。很可能你多年来一直在解决这个问题,通过做(例如,)。如果你继续这样做,它将继续解决问题——所以,不,你不需要修复它。如果您愿意,您可以使用删除上游并停止投诉,并且根本不将本地分支标记为有任何上游。git pull remote branchgit pull origin source--unset-upstreamsource

The point of having an upstream is to make various operations more convenient. For instance, git fetchfollowed by git mergewill generally "do the right thing" if the upstream is set correctly, and git statusafter git fetchwill tell you whether your repo matches the upstream one, for that branch.

有上游的目的是为了让各种操作更方便。例如,如果上游设置正确,则git fetch跟随git merge通常会“做正确的事情”,git status之后git fetch会告诉你你的回购是否与上游的回购匹配,对于那个分支。

If you want the convenience, re-set the upstream.

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



1git pulluses git fetch, and as of Git 1.8.4, this (finally!) also updates the "remote-tracking branch" information. In older versions of Git, the updates did not get recorded in remote-tracking branches with git pull, only with git fetch. Since your Git must be at least version 1.8.5 this is not an issue for you.

1git pull使用git fetch,从 Git 1.8.4 开始,这(终于!)也更新了“远程跟踪分支”信息。在旧版本的 Git 中,更新没有记录在远程跟踪分支中git pull,只有git fetch. 由于您的 Git 必须至少为 1.8.5 版本,因此这对您来说不是问题。

2Well, this plus a configuration line I'm deliberately ignoring that is found under remote.origin.fetch. Git has to map the "merge" name to figure out that the full local name for the remote-branch is refs/remotes/origin/master. The mapping almost always works just like this, though, so it's predictable that mastergoes to origin/master.

2好吧,这加上一个我故意忽略的配置行是在remote.origin.fetch. Git 必须映射“合并”名称才能确定远程分支的完整本地名称是refs/remotes/origin/master. 不过,映射几乎总是像这样工作,因此可以预测masterorigin/master.

3Or, with git config. If you just want to set the upstream to origin/sourcethe only part that has to change is branch.source.merge, and git config branch.source.merge refs/heads/sourcewould do it. But --set-upstream-tosays whatyou want done, rather than making you go do it yourself manually, so that's a "better way".

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

回答by ElazarR

torek's answer is probably perfect, but I just wanted for the record to mention another case which is different than the one described in the original question but the same error may appear (as it may help others with similar problem):

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

I have created an empty (new) repo using git init --bareon one of my servers. Then I have git cloned it to a local workspace on my PC.

我在git init --bare我的一台服务器上创建了一个空的(新的)repo 。然后我把git clone它放到了我 PC 上的本地工作区。

After committing a single version on the local repo I got that error after calling git status.

在本地存储库上提交单个版本后,我在调用git status.

Following torek's answer, I understand that what happened is that the first commit on local working directory repo created "master" branch. But on the remote repo (on the server) there was never anything, so there was not even a "master" (remotes/origin/master) branch.

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

After running git push origin masterfrom local repo the remote repo finally had a master branch. This stopped the error from appearing.

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

So to conclude - one may get such an error for a fresh new remote repo with zero commits since it has no branch, including "master".

所以总结一下 - 对于一个零提交的新远程仓库,可能会出现这样的错误,因为它没有分支,包括“master”。

回答by Ajay Kotnala

This might solve your problem.

这可能会解决您的问题。

after doing changes you can commit it and then

进行更改后,您可以提交它,然后

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

hope it works for you.

希望对你有效。

thanks

谢谢

回答by smremde

For me, .git/refs/origin/masterhad got corrupt.

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

I did the following, which fixed the problem for me.

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

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

回答by user1106400

I had this question twice, and it was always caused by the corruption of the git cache file at my local branch. I fixed it by writing the missing commit hash into that file. I got the right commit hash from the server and ran the following command locally:

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

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

回答by reecha soni

Issue: Your branch is based on 'origin/master', but the upstream is gone.

问题:您的分支基于“origin/master”,但上游已经消失。

Solution: git branch --unset-upstream

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

回答by Pravin

delete your local branch by following command

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

git branch -d branch_name

you could also do

你也可以这样做

git branch -D branch_name 

which basically force a delete (even if local not merged to source)

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

回答by Anne van Rossum

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 repositoriesin 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 .gitignorefile in the $WEBSITEdirectory so that this setup actually works.

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

Enough introduction. In this case the error might also come from the repository in _deploy.

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

cd _deploy

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

In .git/configyou will normally need to find something like this:

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

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

But in your case the branch master does not have a remote.

但在你的情况下,分支主没有遥控器。

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

Which you can solve by:

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

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

So, everything is as torek told you, but it might be important to point out that this very well might concern the _deploydirectory rather than the root of your website.

所以,一切都正如 torek 告诉你的那样,但重要的是要指出这很可能涉及_deploy目录而不是您网站的根目录。

PS: It might be worth to use a shell such as zshwith a gitplugin to not be bitten by this thing in the future. It will immediately show that _deployconcerns a different repository.

PS:为了以后不被这个东西咬到,可能值得用一个shell之类zshgit插件。它将立即显示_deploy涉及不同的存储库。