为什么我必须在本地创建的新分支的上游设置? [英] why do I have to set-upstream of new branch I create locally?
问题描述
我以为我的git配置有问题
I thought I had some problem with my git config,
每次创建新分支时,我首先都必须设置上游
every time i create a new branch I first have to set-upstream
git push --set-upstream sensorAtHome pull-down-to-refresh
其中sensorAtHome
是我的项目名称,而pull-down-to-refresh
是分支名称.
where sensorAtHome
is my project name and pull-down-to-refresh
is branch name.
实际上,我不必在工作场所执行此操作,我只需创建分支即可完成我的工作提交和推送,而不必进行上游设置,但是对于我在家中的项目,当我推送到GitHub.com时,我必须..
Actually I do not have to do it at my work place, I simple create branch do my work commit and push, I never have to set-upstream but for my projects at home when I push to GitHub.com I have to..
我的工作流程中是否缺少某些地方?
Is there something I am missing probably wrong with my workflow ?
推荐答案
假设您的Git的工作版本为2.0之前的版本(您的评论表明它的版本可能为1.8),这就是您的家庭Git(2.0或更高版本)的原因)和工作Git(2.0之前的版本)的行为有所不同.
Assuming your work version of Git is pre-2.0 (your comment suggests it may be 1.8), that would be the reason your home Git (which 2.0 or later) and work Git (pre-2.0) behave differently.
在Git 2.0中,push.default
的默认值从matching
更改为simple
.从Git 1.8.0开始,Git开始产生有关此的警告消息.请参见警告:push.default未设置;详细信息,其隐式值在Git 2.0中进行了更改. Git 2.8.0版删除了警告.
In Git 2.0, the default value for push.default
changed from matching
to simple
. Starting with Git 1.8.0, Git began producing warning messages about this. See Warning: push.default is unset; its implicit value is changing in Git 2.0 for details. Git version 2.8.0 dropped the warning.
请注意,与simple
相比,您可能更喜欢current
.参见与当前" git中的push.default用于分散式工作流程.但是,设置上游非常有用:请参阅为什么我需要一直执行`--set-upstream`?如果愿意,请继续阅读以获取更多背景信息.
Note that you may prefer current
to simple
. See "simple" vs "current" push.default in git for decentralized workflow. However, setting an upstream is useful: see Why do I need to do `--set-upstream` all the time? Read on for more background if you like.
是由于此,还是只是因为您决定配置它,您可能已经在任何特定存储库中或为您自己的全存储库范围内的--global
设置了自己的push.default
值. >设置. (请注意,如果您在某个特定存储库中本地git config --global
某些设置,然后在本地git config
same 设置,则通常会覆盖本地设置.此规则有一些例外,例如, branch.master.fetch
,但是使用--global
将其设置为任何值通常是不明智的!)
Whether as a result of this, or just because you decided you should configure it, you may have set your own value for push.default
, either in any particular repository, or for your own personal all-repositories-wide --global
setting. (Note that if you git config --global
some setting, and then also git config
the same setting locally in one specific repository, the local setting usually overrides. There are a few exceptions to this rule, e.g., for branch.master.fetch
, but it tends to be unwise to set this to anything with --global
!)
如果未设置 ,或者在工作设置中将其显式设置为matching
,但在家庭设置中显式设置为simple
.这两种模式的不同动作解释了这个问题. matching
的行为在警告的可接受答案中有所描述.它的隐式值在Git 2.0中发生了变化,并且在"git push"的默认行为中发生了更多变化.没有指定分支,但请注意,这两个都描述了您在运行时会得到的结果:
If you have not set it, or have set it explicitly to matching
in your work setup but to simple
in your home setup. the different actions of these two modes explain the issue. The behavior of matching
is somewhat described in the accepted answer to Warning: push.default is unset; its implicit value is changing in Git 2.0, and much more in Default behavior of "git push" without a branch specified—but note that both of these describe what you get if you run:
git push sensorAtHome
或:
git push
但不是:
git push sensorAtHome pull-down-to-refresh
更确切地说,描述总是始于谈论在没有 refspecs 的情况下进行推送时发生的情况. (我们稍后将介绍refspecs.)
More precisely, descriptions always start out talking about what happens when you push with no refspecs. (We'll get to refspecs in just a moment.)
push.default
实际上有五个可能的设置(尽管新标准simple
仅在Git版本1.7.11中引入,并且仍然有人在使用Git 1.7).这五个设置是nothing
,current
,upstream
,simple
和matching
.
There are actually five possible settings for push.default
(although the new standard simple
was only introduced in Git version 1.7.11, and there are still some people using Git 1.7). These five settings are nothing
, current
, upstream
, simple
, and matching
.
nothing
设置实际上是所有设置中最简单的设置,但我尝试过后发现它很烦人. :-)它强制您命名要推送的分支.因此,我们几乎可以忽略它,而只考虑其他四个.
The nothing
setting is actually the simplest of all, but I tried it and found it annoying. :-) It forces you to name which branch you want to push. Because of this, we can mostly ignore it and only think about the other four.
如果您未指定任何分支,则其他四个设置将指示某个分支或多个分支推动 .更准确地说,如果您忽略所有 refspecs ,则这四个设置会直接起作用.但是它们也会影响当您 include 一些参考规范时会发生什么.
The other four settings will intuit some branch or branches to push if you don't specify any branches. More precisely, these four settings intuit things if you leave out all the refspecs. But they can also affect what happens when you include some refspecs.
git push
的语法,如果我们忽略所有标志参数,则为:
The syntax for git push
, if we ignore all the flags arguments, is:
git push <repository> <refspec> <refspec> ...
也就是说,存储库是git push
之后的 first 参数(也会跳过所有标志和标志参数).您可以在此处写出完整的网址,例如:
That is, the first argument after git push
(also skipping any flags and flag arguments) is the repository. You can write out a full URL here, e.g.:
git push https://github.com/...
,但是通常使用 remote 更好,后者是origin
之类的缩写,在您的情况下为sensorAtHome
.对于git push
,远程大多数情况下只是避免每次都必须键入长URL(对于git fetch
,它 也提供了远程跟踪分支的origin/
部分). >名称).
but it's usually much nicer to use a remote, which is a short name like origin
, or in your case, sensorAtHome
. For git push
, the remote mostly just avoids having to type a long URL each time (for git fetch
it also provides the origin/
part of the remote-tracking branch names).
在 repository 参数之后,其余的参数均为 refspecs .实际上,repository参数是可选的,但是如果您要提供任何refspec参数,则必须必须首先提供一个 repository 参数.但是 到底是什么?我们为什么要关心他们?
After the repository argument, any remaining arguments are refspecs. The repository argument is actually optional, but if you want to give any refspec arguments at all, you must provide a repository argument first. But what exactly is a refspec? Why would we care about them?
refspec最简单的形式就是您在这里使用的形式:它只是一个分支名称.您写道:
The simplest form of a refspec is the one you are using here: it's just a branch name. You write:
git push someremote branch
和Git推送命名的分支.但是refspec实际上更为通用.
and Git pushes the named branch. But refspecs are actually much more general.
首先,refspec开始时,两个部分之间用冒号隔开.例如,您不仅可以说branch
,还可以编写:
First, a refspec starts off with two parts separated by a colon. For instance, instead of just saying branch
, you can write:
git push someremote branch:branch
左侧的名称是您的名称,右侧的名称是其名称.请记住,当您运行git push
时,您正在使用具有两个不同存储库的两个 Gits.您正在告诉您的Git调用一些远程Git.一旦您的Git在互联网电话上(通过https或ssh或其他方式)将另一个Git包含在您的Git中,您的Git会将您的一些提交发送到其Git,然后您的Git要求他们设置他们的分支,通常基于您刚刚发送的提交.
The name on the left is your name, and the name on the right is their name. Remember that when you run git push
, you are using two Gits, with two different repositories. You are telling your Git to call up some remote Git. Once your Git has the other Git on the Internet-phone (via https or ssh or whatever), your Git sends some of your commits to their Git, and then your Git asks them to set their branches, usually based on the commits you just sent.
由于有两个Git,因此涉及两个不同的分支名称.例如,您的分支机构可能命名为Fred,而其分支机构可能命名为Frederick-the-Great.您的可能是Zaphod,他们的可能是Beeblebrox.您的分支是您的,而他们的分支可能是您的上游.不需要它们具有相同的名称-嗯,几乎没有要求.而且,如果您按字面意义拼写了这两个部分,编写zaphod:beeblebrox
或其他内容,Git会假定您知道自己在做什么,然后运行.
Since there are two Gits, there are two different branch names involved. Your branch might be named Fred, and theirs might be named Frederick-the-Great, for instance. Yours might be Zaphod and theirs might be Beeblebrox. Your branch is yours, and their branch is probably your upstream. There's no requirement that they have the same name—well, almost no requirement. And, if you literally spell out both parts, writing zaphod:beeblebrox
or whatever, Git assumes you know what you are doing, and runs with that.
但是,如果这些名称不相同相同,事情就会变得很疯狂.如果它们始终匹配,则简单.因此,四个有趣的"设置中的三个(matching
,current
和simple
)尝试确保它们保持相同的状态.您只需要使用您的名称,Git就会尝试确保其名称匹配.
Things get pretty crazy if these names are not the same, though. It's much simpler if they match all the time. So, three of the four "interesting" settings—matching
, current
, and simple
—try to make sure they stay the same. You just need to use your names, and your Git will try to ensure that their names match up.
一个不执行此设置的设置-upstream
模式-告诉您的Git在您的一侧使用您的名称,以及您配置为上游的任何名称>在其一侧进行设置.显然,要使其正常工作,您必须设置一个上游.但这仍然留下matching
,current
和simple
,并且可能会让您想知道它们的用途.
The one setting that does not do this—the upstream
mode—tells your Git to use your name on your side, and whatever you have configured as the upstream setting on their side. Obviously, for this to work, you must set an upstream. But this still leaves matching
, current
, and simple
, and may leave you wondering what they are for.
简短的回答是matching
是Git最初所做的,但事实证明这是一个错误,您可能永远都不要使用它.您应该改用simple
或current
. simple
设置更安全,但要求您设置上游.再次说明一下,并帮助您在它们之间进行选择,请参见与当前" git中的push.default用于分散式工作流程.
The short answer is that matching
is what Git did originally, but it turned out to be a mistake and you probably should never use it. You should use either simple
or current
instead. The simple
setting is safer, but requires that you set an upstream. Again, for a bit more and to help you choose between them, see "simple" vs "current" push.default in git for decentralized workflow.
如果您提供至少一个refspec,则旧的matching
设置的作用与current
相同.您的Git会使用您提供的一个或多个refspec(即分支名称),并且请记住,这仅适用于您未编写local-name:remote-name
的情况,因此只有一个本地名称,并且他们的Git使用以下命令创建或更新了一个分支相同的名称,您的分支是否具有上游设置..但是,如果您忽略了 all refspec,则matching
告诉您的Git向他们的Git询问有关所有其分支,并查找所有您的分支,并匹配名称.无论名称相同,您的Git都会将提交内容发送到其Git,并要求他们设置其同名分支.
If you provide at least one refspec, the old matching
setting works just like current
. Your Git takes the refspec or refspecs (i.e., branch name) you provided—and remember, this is only for when you didn't write local-name:remote-name
, so there's just a local name—and has their Git create or update a branch with the same name, whether or not your branch has an upstream set. But if you leave out all the refspecs, matching
tells your Git to ask their Git about all their branches, and look up all your branches, and match up the names. Wherever the names are the same, your Git sends your commits to their Git, and asks them to set their same-named branch.
对于大多数人而言,大多数时候这种差异很小.您有您的master
,也许还有您的develop
和一个或两个功能分支.您git fetch
拿起新东西,工作一会儿,然后git push
发送您写的东西.您的Git要求他们的Git更新功能分支的master
和 develop
和.如果您不应该在master
,和上工作,那么您不是在master
上工作-仅在develop
上工作-develop
更改被推送,并且您尝试从其master
中删除其新提交时遇到错误.
For most people, at most times, this difference is small. You have your master
, and maybe your develop
and a feature branch or two. You git fetch
to pick up new stuff, work for a while, and git push
to send what you wrote. Your Git asks their Git to update master
and develop
and your feature branches. If you were not supposed to be working on master
, and you didn't work on master
—just on develop
—there's nothing in your master
for your Git to push, so there is no problem. Even if someone else pushed something new to the other Git's master, you just get part of your push rejected with an error: your develop
changes get pushed and your attempt to remove their new commits from their master
meets with an error.
但是,请看:您只是要求Git从其master
中删除其新提交.如果没有别的,那是一个不好的信号.而且,如果您在功能分支上做了一些实验性工作,但实际上还没有准备好推送,并且您打算修复某些东西并重新定位该功能分支中的一些错误提交,则您可能不小心将了 both develop
和该功能分支.
But look: you just asked your Git to delete their new commits from their master
. That's a bad sign, if nothing else. And, if you did some experimental work on a feature branch, and it's not actually ready to push yet and you plan to fix some stuff and rebase some bad commits away in that feature branch, you may have just accidentally pushed both develop
and that feature branch.
这很糟糕. current
设置与matching
设置非常相似,但是默认情况下它仅推送一个分支,这是您现在签出的分支.
It's just bad all around. The current
setting is a whole lot like the matching
setting, but it pushes only one branch by default, which is the one you have checked out now.
simple
设置与current
设置一样,但增加了一条安全带:当前分支需要在另一个Git中具有相同名称的分支上设置上游设置.
The simple
setting is just like the current
setting, but adds one more safety belt: the current branch needs to have its upstream set, to a branch of the same name in the other Git.
出于完整性考虑,我想谈谈有关refspec的更多信息.一种是它们不必命名branche:您也可以命名标签.只要您不同时对标签和分支使用相同名称(只要不要这样做,Git就会知道您的意思)为发生的事情定义了一套规则,但是它们很奇怪且容易引起冲突,会使您感到困惑.您可以拼写任何引用的全名":refs/heads/master
,refs/tags/v1.2
,依此类推.您可以通过写:delete
来省去本地名称,该命令要求其Git 删除分支或标签或其他引用.最后,您可以设置每个引用的 force 标志.
For completeness, I want to mention a few more things about refspecs. One is that they don't have to name branche: you can also name tags. Your Git will generally figure out which one you mean, provided you don't use the same name for both a tag and a branch (don't do this—Git has a defined set of rules for what happens, but they are weird and conflict-y and will confuse you). You can spell out the "full name" of any reference: refs/heads/master
, refs/tags/v1.2
, and so on. You can leave out the local name, by writing :delete
, which asks their Git to delete a branch or tag or other reference. Last, you can set a per-refspec force flag.
这些是push.default
的五个可能的设置:
These are the five possible settings for push.default
:
-
nothing
:您必须至少包含一个 refspec 参数(这也将强制您包括 remote 部分).您不会真的在这个设置上出错.问题是,这很烦人,即您也不能走对头. -
matching
:这是2.0之前的旧Git行为.它会推动太多分支,因此除非您确实很固执,否则不要使用它. :-) -
current
:这是matching
表现更好的变体. -
simple
:这与current
相同,但增加了安全性检查,即分支需要具有相同的基本分支名称的上游集.安全检查可能有点烦人:它迫使您设置上游.但是,设置上游不仅具有使simple
高兴的价值,因此对于大多数人来说,这实际上是大多数时间最好的push.default
. -
upstream
:这是针对稍微发疯的情况,由于某些原因,即使上游是ginger
,您也必须命名分支fred
.这是simple
的一种更宽容的变体:您仍然必须设置上游,但是可以将其设置为在疯狂的火车上旅行.
nothing
: you must include at least one refspec argument (which forces you to include the remote part as well). You can't really go wrong with this setting; the problem is that it's quite annoying, i.e., you can't just go right either.matching
: this is the old, pre-2.0 Git behavior. It can push too many branches, so don't use it unless you're really stubborn. :-)current
: this is the better-behaved variant ofmatching
.simple
: this is the same ascurrent
with the added safety-check that your branch needs to have an upstream set, with the same basic branch name. The safety-check can be slightly annoying: it forces you to set the upstream. Setting the upstream has value other than just makingsimple
happy, though, so this is really the bestpush.default
for most people most of the time.upstream
: this is for the slightly-crazy-making case where, for some reason, you have to name your branchfred
even though the upstream isginger
, or whatever. It's kind of a more permissive variant ofsimple
: you still have to set the upstream, but you can set it to take a trip on the crazy train.
这篇关于为什么我必须在本地创建的新分支的上游设置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!