为什么要调用git分支--unset-upstream修复? [英] Why call git branch --unset-upstream to fixup?

查看:3307
本文介绍了为什么要调用git分支--unset-upstream修复?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当谈到git的高级操作时,我更喜欢新手。我使用博客框架博客 > Octopress 。虽然Octopress自2011年以来没有任何发展,但它对我的目的很好,所以我没有想过改变任何东西。

仅供参考,我的博客托管于Github页面。



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

 分支源
您的分支基于'origin / master',但上游消失了。
(使用git branch --unset-upstream来修正)

重复所有后续命令,如 git add。 git commit -m'message' git push origin source


  • 这条消息是什么意思?

  • 有什么东西坏了?

  • 如果是,什么?

  • 我需要修复吗?



如果可能的话,请指出一篇pdf / web文章,我可以在此阅读并理解它以备将来之用。




$ b $ -b $ -b $




$ b $ -b $ $ $ git branch -a
*源
遥控器/八分器/ 2.1
遥控器/八分器/ HEAD - >八度/大师
遥控器/八音板/ gh-pages
遥控器/八音色/ linklog
遥控器/八音色/大师
遥控器/八音色/ refactor_with_tests
遥控器/八音色/ ruby​​gemcli
remotes / octopress / site
remotes / origin / source

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

解决方案

TL; DR版本:远程分支 origin / master 曾经存在,但现在不存在,因此本地分支 source 正在跟踪不存在的东西,这在最好的情况下是可疑的 - 这意味着不同的git功能无法做到什么都适合你 - 而git会警告你。如果没有上游跟踪功能,您一直处于良好状态,因此您是否需要更改任何内容。






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



  • git branch -v -v (和git status)没有区分不是基于任何其他分支的
    分支,
    中的分支与其上游分支同步,而是使用
    上游分支不再存在。

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

每个remote只是一个名称,如<$ c $在这种情况下,c> origin 或 octopress 。他们的目的是记录诸如 git fetch git pull 更新地点的完整网址。当您使用 git fetch remote 时, 1 git转到该远程位置(使用保存的URL)适当的更新集。它还使用远程分支来记录更新。

远程分支仅仅是某个远程上最后看到的分支的记录。每个远程本身就是一个git仓库,所以它有分支机构。远程origin上的分支记录在 remotes / origin / 下的本地存储库中。您显示的文本表明,在 origin 上有一个名为 source 的分支,名为 2.1的分支, linklog ,依此类推 octopress



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



<最后,您可以设置一个(本地)分支来跟踪远程分支。一旦本地分支被设置为跟踪远程分支 R ,git会调用它的上游,并告诉你是否前进和/或后面的上游(在承诺条款)。对于本地分支和远程分支来说,使用相同的名称(远程前缀部分除外)是正常的(甚至可以推荐),例如 source origin / source ,但实际上并非必要。在这种情况下,这不会发生。您有一个本地分行跟踪远程分行原产地/主人



你不需要知道 的确切机制 git设置本地分支来跟踪远程分支,但它们在下面是相关的,所以我将展示如何这工作。我们从您的本地分行名称开始, source 。有两个使用此名称的配置条目,拼写为 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 / ...和下面列出,没有远程/起源/主控 的。据推测,有一次,但它现在已经消失。



Git告诉你可以使用<$ c 删除跟踪信息$ C> - 取消设置上游。这将清除 branch.source.origin branch.source.merge ,并停止警告。 p>

尽管如此,您希望切换来追踪 origin / master ,以跟踪其他内容:可能 origin / source ,但可能是 octopress / 名称之一。 p>

你可以用 git branch --set-upstream-to 3
$ b $ pre $ $ $ $ $ $ $ g $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $'

(假设您仍在分支源中,并且 origin / source 是上游你想 - 没有办法告诉哪一个,如果有的话,你实际上想要的,但)。

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

你在这里是当你第一次做一个 git clone的时候,你克隆的东西有一个分支 master 。您还有一个分支 master ,它被设置为跟踪 origin / master (这是一个正常的标准设置,用于GIT)。这意味着你有 branch.master.remote branch.master.merge set,来源和参考/标题/主标记。但是你的 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 远程分支 (例如, git pull origin source )。如果你一直这样做,它会继续解决问题 - 所以,不,你不需要来修复它。如果你喜欢,你可以使用 - unset-upstream 来移除上游并停止投诉,并且不要有本地分支 source 标记为拥有任何上游。



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



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




git pull 使用 git fetch ,并且从git 1.8.4开始,this(终于!)也更新了远程分支信息。在旧版本的git中,这些更新没有在 git pull 的远程分支中记录,只有 git fetch 。既然你的git必须至少是1.8.5版本,这对你来说不是问题。



2 好了,这加上一个配置行I '故意忽略它可以在 remote.origin.fetch 下找到。 Git必须映射合并名称以确定远程分支的完整本地名称是 refs / remotes / origin / master 。但映射几乎总是像这样工作,所以可以预见, master 会转到 origin / master 。 p>

3 或者, git config 。如果您只想将上游设置为 origin / source ,唯一必须更改的部分是 branch.source.merge git config branch.source.merge refs / heads / source
会这样做。但是 - set-upstream-to 表示你想完成什么,而不是让你自己手动完成,所以这是一个更好的方法 。


I'm more of a novice when it comes to advanced operations in git. I maintain my blog using 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.

FYI, my blog is hosted on Github Pages.

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

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.

  • 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.

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.

解决方案

TL;DR version: remote branch origin/master used to exist, but does not now, so local branch source is 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.


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 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.

To describe what it means, you first need to know about "remotes", "remote branches" and how git handles "tracking an upstream".

Each "remote" is simply a name, like origin or octopress in this case. Their purpose is to record things like the full URL of the places from which you git fetch or git pull updates. When you use git fetch remote,1 git goes to that remote (using the saved URL) and brings over the appropriate set of updates. It also records the updates, using "remote branches".

A "remote branch" is simply a recording of a branch 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 source on origin, and branches named 2.1, linklog, and so on on 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 branch". Once local branch L is set to track remote branch R, git will call R its "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 branches to use the same name (except for the remote prefix part), like source and origin/source, but that's not actually necessary.

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

You're not supposed to need to know the exact mechanics of how git 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.remote and 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 config --get branch.source.remote
origin
$ git config --get branch.source.merge
refs/heads/master

Putting these together,2 this tells git that your branch source tracks your "remote branch", origin/master.

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

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

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

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

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

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

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

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.

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.


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 need to fix it. If you like, you can use --unset-upstream to remove the upstream and stop the complaints, and not have local branch source marked as having any upstream at all.

The point of having an upstream is to make various operations more convenient. For instance, git fetch followed by git merge will generally "do the right thing" if the upstream is set correctly, and git status after git fetch will tell you whether your repo matches the upstream one, for that branch.

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


1git pull uses git fetch, and as of git 1.8.4, this (finally!) also updates the "remote branch" information. In older versions of git, the updates did not get recorded in remote 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.

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 master goes to origin/master.

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

这篇关于为什么要调用git分支--unset-upstream修复?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆