[英]Does `<remote>/<branch>` in this `git checkout` command represent a remote branch or a remote tracking branch?
The manpage of git checkout
says: git checkout
的手册页说:
git checkout <branch>
If
<branch>
is not found but there does exist a tracking branch in exactly one remote (call it<remote>
) with a matching name, treat as equivalent to 如果未找到<branch>
但确实在一个具有匹配名称的远程站点(称为<remote>
)中存在跟踪分支,则将其等同于$ git checkout -b <branch> --track <remote>/<branch>
which, the manpage of git checkout
says, invokes git checkout
的联机帮助页面说
$ git branch -f <branch> <remote>/<branch>
with -t
option to git branch
by default (from manpage of git branch
) 带有-t
选项的git branch
默认情况下(来自git branch
帮助页)
-t
When creating a new branch, set up
branch.<branch>.remote
andbranch.<branch>.merge
configuration entries to mark the start-point branch as "upstream" from the new branch. 创建新分支时,请设置branch.<branch>.remote
和branch.<branch>.merge
配置条目,以将起点分支标记为新分支的“上游”。
What does <remote>/<branch>
in the equivalent git checkout
command and in the git branch
command represent? 等效的git checkout
命令和git branch
命令中的<remote>/<branch>
代表什么?
Since the git branch
command sets up branch.<branch>.remote
and branch.<branch>.merge
to be a remote repository and a remote branch, does <remote>/<branch>
represent the remote branch (the upstream branch to-be)? 由于git branch
命令设置了branch.<branch>.remote
和branch.<branch>.merge
成为远程存储库和远程分支,因此<remote>/<branch>
代表了远程分支(上游分支为-是)?
Since the git branch
command create a new local branch starting from <remote>/<branch>
, does <remote>/<branch>
represent the remote tracking branch? 由于git branch
命令从<remote>/<branch>
创建一个新的本地分支,所以<remote>/<branch>
代表远程跟踪分支吗?
git help revisions
will tell you how a refname is interpreted. git help revisions
将告诉您如何解释refname。
For reference, 以供参考,
<refname>
, egmaster
,heads/master
,refs/heads/master
<refname>
,例如master
,heads/master
,refs/heads/master
A symbolic ref name. 符号引用名称。 Eg master typically means the commit object referenced by refs/heads/master. 例如,master是指由refs / heads / master引用的提交对象。 If you happen to have both heads/master and tags/master, you can explicitly say heads/master to tell Git which one you mean. 如果您碰巧同时拥有heads / master和tag / master,则可以明确地说出heads / master来告诉Git您是什么意思。 When ambiguous, a is disambiguated by taking the first match in the following rules: 当模棱两可时,通过遵循以下规则中的第一个匹配项来消除a的歧义:
- If $GIT_DIR/<refname> exists, that is what you mean (this is usually useful only for HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD and CHERRY_PICK_HEAD); 如果$ GIT_DIR / <refname>存在,这就是您的意思(通常仅对HEAD,FETCH_HEAD,ORIG_HEAD,MERGE_HEAD和CHERRY_PICK_HEAD有用);
- otherwise, refs/<refname> if it exists; 否则,refs / <refname>(如果存在);
- otherwise, refs/tags/<refname> if it exists; 否则,使用refs / tags / <refname>(如果存在);
- otherwise, refs/heads/<refname> if it exists; 否则,refs / heads / <refname>(如果存在);
- otherwise, refs/remotes/<refname> if it exists; 否则,引用/远程/ <refname>(如果存在);
otherwise, refs/remotes/<refname>/HEAD if it exists. 否则,引用/远程/ <refname> / HEAD(如果存在)。
HEAD
names the commit on which you based the changes in the working tree.HEAD
命名工作树中所做更改的基础提交。 FETCH_HEAD records the branch which you fetched from a remote repository with your last git fetch invocation. FETCH_HEAD记录您最近一次git fetch调用从远程存储库获取的分支。 ORIG_HEAD is created by commands that move your HEAD in a drastic way, to record the position of the HEAD before their operation, so that you can easily change the tip of the branch back to the state before you ran them. ORIG_HEAD是由命令创建的,这些命令以剧烈的方式移动HEAD,以在操作之前记录HEAD的位置,以便您可以轻松地将分支的尖端更改回运行之前的状态。 MERGE_HEAD records the commit(s) which you are merging into your branch when you run git merge. MERGE_HEAD记录运行git merge时要合并到分支中的提交。 CHERRY_PICK_HEAD records the commit which you are cherry-picking when you run git cherry-pick. CHERRY_PICK_HEAD记录您在运行git cherry-pick时正在选择的提交。Note that any of the refs/* cases above may come either from the $GIT_DIR/refs directory or from the $GIT_DIR/packed-refs file. 请注意,上面的任何refs / *案例都可能来自$ GIT_DIR / refs目录或$ GIT_DIR / packed-refs文件。 While the ref name encoding is unspecified, UTF-8 is preferred as some output processing may assume ref names in UTF-8. 虽然未指定引用名称编码,但首选使用UTF-8,因为某些输出处理可能会假定UTF-8中使用了引用名称。
@
@ alone is a shortcut for HEAD. @单独是HEAD的快捷方式。
So when you say origin/master
and Git's looking for something in the repo there, it'll search according to that list and unless you've taken to punning your remote names with branch or tag prefixes it'll find the remote-tracking ref refs/remotes/origin/master
. 因此,当您说origin/master
且Git在那里的仓库中寻找东西时,它将根据该列表进行搜索,除非您习惯使用分支或标签前缀来修剪远程名称,否则它将找到远程跟踪引用refs/remotes/origin/master
。
(note that there are a lot of handy ways to refer to this or that set of revisions in Git, see the docs). (请注意,有很多便捷的方法可以在Git中引用此版本或该版本的修订,请参见文档)。
See jthill's answer for how things work normally, which is how they should work. 见jthill的答案的事情通常是如何工作的,这是他们应该如何工作。
There's a nasty little wrinkle here if you configure your remote.origin.fetch
to an unusual set of strings, though. 但是,如果将remote.origin.fetch
配置为一组不寻常的字符串,那么这里会有一个令人讨厌的小皱纹。 Both git fetch
and git checkout
—well, anything that uses a branch's upstream, really—wind up using a data structure that Git calls a refmap . git fetch
和git checkout
(实际上,任何使用分支上游的东西)都使用Git调用refmap的数据结构结束 。 Note that there is never, as far as I can tell, any good reason to do what I am about to describe. 请注意,据我所知,从来没有任何正当理由做我将要描述的事情。 But Git does it (based on the user's configuration), so we must be aware of its behavior if we wish to program Git correctly when writing our own code to use Git configurations. 但是Git会这样做 (基于用户的配置),因此,如果我们希望在编写自己的代码以使用 Git配置时希望正确地对Git进行编程,则必须意识到它的行为。
Let's say, for example, that you configure remote.origin.fetch
this way: 例如,假设您remote.origin.fetch
这种方式配置remote.origin.fetch
:
[remote "origin"]
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/develop:refs/remotes/origin/weird_develop
Now when you run: 现在,当您运行时:
git fetch origin
you'll get their refs/heads/master
and record it in your own repository as refs/remotes/origin/master
, quite normally. 您通常会得到他们的refs/heads/master
并将其记录在自己的存储库中,作为refs/remotes/origin/master
。 But you'll treat their refs/heads/develop
differently , creating or updating your own refs/remotes/origin/weird_develop
in your own repository. 但是,你对待他们的refs/heads/develop
不同 ,在创建或更新自己的refs/remotes/origin/weird_develop
在自己的仓库。
Hence, your remote-tracking branches that remember their master
and develop
are called origin/master
and origin/weird_develop
(for short) in your repository, even though they are called master
and develop
in their repository. 因此,能记住他们的远程跟踪分支master
和develop
被称为origin/master
及origin/weird_develop
在你的仓库(简称),即使他们被称为master
,并develop
他们的仓库。
Now suppose you'd like to create your own branch named develop
. 现在,假设您想创建自己的名为develop
的分支。 If you were using sane fetch =
configurations, its upstream setting—what git rev-parse --abbrev-ref develop@{upstream}
prints—would be origin/develop
. 如果您使用的是合理的 fetch =
配置,则其上游设置( git rev-parse --abbrev-ref develop@{upstream}
打印)将是origin/develop
。 But for some (not-sane?) reason, you've configured this rather bizarre set of fetch =
settings, so running git fetch
creates or updates one weirded remote-tracking name. 但是出于某些(不是理智的?)原因,您已经配置了一组相当奇怪的fetch =
设置,因此运行git fetch
会创建或更新一个奇怪的远程跟踪名称。
Despite the weird remote-tracking names, the branch configurations will use the actual branch names on the upstream. 尽管远程跟踪名称很奇怪,但分支配置将在上游使用实际的分支名称。 That is, inspecting .git/config
after doing: 也就是说,在执行以下操作后检查.git/config
:
git checkout --track develop origin/weird_develop
you will see: 你会看见:
[branch "develop"]
remote = origin
merge = refs/heads/develop
The question you should ask is: How did Git put refs/heads/develop
into this entry, when my upstream setting is origin/weird_develop
? 您应该问的问题是: 当我的上游设置是origin/weird_develop
时,Git是如何将refs/heads/develop
放入origin/weird_develop
?
The answer is that Git has built this refmap thing, that says that their (origin's) refs/heads/develop
is your refs/remotes/origin/weird_develop
. 答案是Git已经构建了这个refmap东西,也就是说他们的 (来源) refs/heads/develop
是您的refs/remotes/origin/weird_develop
。 This refmap goes both ways: Git can either look up their refs/heads/develop
to find your remote-tracking name, or Git can look up your refs/remotes/origin/weird_develop
to find origin's branch name. 此refmap有两种方式:Git可以查找其refs/heads/develop
来查找您的远程跟踪名称,或者Git可以查找您的refs/remotes/origin/weird_develop
来查找来源的分支名称。
For all this to work, the refmap constructed from the fetch =
setting must not change dynamically. 为了使所有这些都能起作用,从fetch =
设置构造的refmap不得动态更改。 That is, if you edit your .git/config
file and alter the fetch
lines semi-randomly, your own Git will start to behave oddly, once the constructed refmap no longer matches reality, or if you create maps that are not proper bijections. 也就是说,如果您编辑.git/config
文件并半随机地更改fetch
线,一旦构造的refmap不再与现实匹配,或者您创建了不正确的双射图,则您自己的Git将开始表现异常。 1 1个
By bijection here, I mean that every name that you do copy from the remote should map to a unique remote-tracking name in your own repository, and this should cover the entire set of remote-tracking names in your repository. 这里的双射是指您从远程复制的每个名称都应映射到您自己的存储库中的唯一远程跟踪名称,并且该名称应覆盖存储库中的整个远程跟踪名称集。 The simple case of +refs/heads/*:refs/remotes/origin/*
obviously meets this criterion. +refs/heads/*:refs/remotes/origin/*
的简单情况显然符合该标准。 However, if you say, for instance: 但是,例如,如果您说:
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/heads/master:refs/remotes/origin/extra_master
you've created a multivalued function in the origin-to-local-repository direction, since master
must be copied to two names, and a surjective mapping in the reverse direction, since your origin/master
and origin/extra_master
both map to their master
. 您已经在origin-to-local-repository方向上创建了一个多值函数 ,因为必须将master
复制到两个名称,并在相反的方向上创建了一个射影映射,因为您的origin/master
和origin/extra_master
都映射到了他们的master
。 Git will stop with various errors for these cases. 对于这些情况,Git会因各种错误而停止。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.