何时创建和更新远程跟踪分支? [英] When are remote-tracking branches created and updated?

查看:105
本文介绍了何时创建和更新远程跟踪分支?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 如果我是正确的,则可以在克隆远程存储库时创建远程跟踪分支。是否还有其他情况下创建远程追踪分支?

  2. 如果我是正确的,远程追踪分支会在从远程获取/提取时更新库。是否还有其他的情况,当一个远程追踪分支被更新?
  3. 作为2的特例,当 git push 本地分支到远程存储库, ,执行 git push 更新远程跟踪分支,或者远程跟踪分支只能通过运行 git fetch git pull > git push


  4. 作为1的特例,如果 git push 将本地非跟踪分支推送到远程分支(即如果没有对应的远程分支到本地分支机构将被推送),将 git push 创建与本地非跟踪分支关联的远程跟踪分支,并将它们转换为本地跟踪分支?



解决方案



    li> ...在克隆远程存储库时可以创建远程跟踪分支。在创建远程追踪分支时是否还有其他情况?


他们是;至少可能是的,但我们稍后再讨论。



特别是,当 git clone 克隆另一个存储库,它为远程添加一个 fetch = 配置行。添加的行取决于以下两个选项:


  • - origin name :改变远程的名字。通常这个名字只是 origin ,而获取配置是 fetch = + refs / heads / *:refs / remotes / origin / * ,但是如果您将远程的名称更改为 zerblatt ,则会得到 + refs / heads / *:refs / remotes / zerblatt / *


  • - mirror 配置读取 fetch = + refs / *:refs / * 。请注意,在这种情况下,可能根本没有远程追踪分支,因为远程追踪分支只是一种简单的抽象方式,在 refs / remotes / name-space,现在我们没有任何重命名。 (如果正在克隆的存储库显示自己的远程跟踪分支,那么 refs / remotes / -they 将会被复制,而我们的我们可能会运行 git ls-remote 来找出他们在我们开始克隆之前所拥有的引用,以便发现,尽管这有点棘手,因为如果我们还没有开始克隆,我们没有配置远程的存储库,以便使用 git ls-remote 。 )


    让我们继续:



    $ b
  • blockquote>


    1. 如果我是对的,远程跟踪分支会在从远程存储库获取/提取时更新。是否还有其他一些远程追踪分支更新的情况?


    是:特别是远程 - 在至少一些成功的 git中,跟踪分支(它同样只是 refs / remotes / 名称空间中的引用)被自动更新推送操作。究竟哪个取决于你的git版本,因为 push 并不总是更新它们:文档注意到这个更新首先出现在git 1.8中。 4虽然更新可能在git 1.7左右;而git 1.9及更高版本也会在所谓的三角形工作流程中进行更新(从一个远程获取,并推送到不同的远程)。




    让我稍微休息一下,并提供一些关于远程跟踪分支的注释。

    正如我们已经提到的,远程跟踪分支是只需一个全称以 refs / remotes / 开头的引用。你(或任何人或任何脚本)可以用来更新任何引用,Git有一个管道命令 git update-ref 。例如,假设你最近从 origin 取得了,然后向你自己的 master 添加了一个提交(这是设置的以origin / master作为上游),因此 git status 表示您前进1。如果你要运行:

      git update-ref refs / remotes / origin / master master 

    ,然后运行 git status ,你的git会声称你现在是up-至今。发生了什么事情是,你已经告诉你的git,他们的主人( origin / master )指向与你自己相同的提交,即使你没有推自己的提交承诺。 (如果你运行这个,你可以简单地运行 git fetch origin 来修正 refs / remotes / origin / master ,或者使用 git update-ref 来修复它。)



    这里揭示了底层机制:git简单写到 refs / remotes / origin / master ,你的git在与其(远程)git交谈时看到的提交对象的实际SHA-1 ID。这有一个很强的约束:除非SHA-1 ID对应于已存储在您自己的存储库中的实际对象,否则git 不能放入该SHA-1 ID。在实践中,git在成功读取或推送后感觉(并且)是安全的,因为在成功读取之后,必须拥有该对象并完成一次推送,必须拥有该对象,并且这两种情况下,git刚刚已经看到该ID对应于给定远程上的某个名称。



    这也显示了 git status 可以首先说提前1:它只是计数从您的主站上游无法访问的 master 可访问的提交。即:

      ahead = $(git rev-list --count master @ {u} .. master)
    后面= $(git rev-list --count master..master @ {u})
    echo分支主人在前$前后$后$

    此信息与上次远程跟踪分支的正确更新时间相同(或过时)。



    现在让我们来注意一下, git clone 可以分成几个独立的git命令。假设您使用 - origin - mirror 都不克隆,并且url简单地为(并且这些步骤都不会失败):

      mkdir myclone& &安培; cd myclone&& git init 
    git remote add origin $ url $ b $ git fetch origin $ b $ git checkout ...

    (到底是什么 git checkout 有点神秘;而 git fetch 命令可以跳过,如果我们添加 -f git remote add 行,但我打算在这里用于说明目的)。每个命令的作用是什么?




    • mkdir + cd + git-init序列创建一个新的空的适合克隆的存储库。 / li>
    • git remote add 行配置远程 origin 以从 $ url 并添加一个 fetch = + refs / heads / *:refs / remotes / origin / * line。
    • >
    • 然后, git fetch origin 命令大多完成了克隆过程(缺少的位是最后的 git checkout < code $)。


      现在,假设我们运行 git fetch origin ,我们运行了其他的git命令,例如 git config --edit 并且混淆了 fetch = 行。我们可以设置,以便我们不会获得远程跟踪分支。我们可以创建自己的提交,与实际的远程实例无关,并使用 git update-ref 将它们分配给远程跟踪分支。我们可以运行 git ls-remote 来查找远程存在的分支。



      这些都不是特别的有用,但它们都是可能的。 (如果有人有任何 good 理由通过创建大量 fetch = 行来进行棘手的分支名称映射,可能它们是有用的)



      (我们应该怎样 git checkout ,在最后一行?答案取决于几件事情,只有其中一些我们可以直接控制,如果你用 -b branch 运行 git clone ,那就是我们可以很容易地处理:我们应该 git checkout branch 。如果有一个 refs / remotes / origin / branch ,我们会得到一个本地分支分支,其上游设置为 origin / branch 。如果您没有指定 -b 选项,然而,要模拟你的git的 git clone 取决于两个你的版本的git和 remote的版本,以及我们从 git ls-remote 中看到的内容。请求并接收分支名称。较旧的选项采用[inte等价于ls-remote输出,并将远程git为 HEAD 显示的SHA-1与远程git为每个分支显示的SHA-1进行比较:如果确切地说一场比赛,那就是分支;如果有多场比赛,可以任意选一场;如果根本没有匹配,请使用 master 。如果一个较新的git与一个不支持新的通过名称告诉我分支选项的较旧的git对话,那么较新的git会回退到较旧的方法。)



      < hr>

      回到您的问题:



      1. 作为2的一个特例,如果本地分支在本地存储库中有一个关联的远程跟踪分支,那么当 git push 一个本地分支到远程存储库时如果本地分支是一个本地跟踪分支,由Loeliger 2ed在Git版本控制中定义),那么 git push 会更新远程跟踪分支或远程跟踪分支可以通过在之后运行 git fetch git pull 来间接更新分支, git push


      我发现这个问题令人困惑。这里没有特殊的外壳。在某些时候,我们知道你的 git push 决定发送远程的 R a请求实际上说:请将您的 refs / heads / foo 设置为SHA-1 1234567890123456789012345678901234567890 (根据需要替换正确的 refs / heads / 名称和SHA-1 ID)。 (当使用 - force-with-lease 时,请求中会包含更多信息,并且在任何情况下,请求还会带有强制标志。以决定是否遵守强制标志但是,在这里需要注意的是,请求提供了一个原始的SHA-1,而不是你的分支在本地git仓库中的名称。 git只能得到他的引用名和SHA-1,这实际上意味着远程的前后接收和更新钩子看不到你的分支名称[它们不也可以看到force flag,我认为这是一个小错误,但这完全是另一个问题。])



      他们的git用yes,完成或否:错误:<细节>答案。

      然后,你的git可以选择将yes,done答案视为足以更新远程 <$ c $的远程追踪分支C> - [R 。 (当然,否的回复意味着没有什么需要更新)。你所在的当地分支(如果有的话),你拥有的当地分支以及是否有上游分支都没有关系。这部分是因为这个相同的代码允许你这样做:

        git push origin 1234567890123456789012345678901234567890:refs / heads / foo 

      将它们的 refs / heads / foo 设置为提交(假设提交ID是有效的;你的git会首先检查你的仓库,并且像往常一样必要时将提交提交给他们的git)。



      就做远程跟踪分支更新而言,git正在弄清楚你的git应该用什么名字替换 refs / heads / foo 。这就是线性和三角形工作流程的内容,以及我们必须检查哪个版本的git。如果你使用的是三角形工作流,而你的git大于1.9,那么你的git不知道要更新什么,并且什么都不更新。如果你的git年龄大于1.7左右,它就不会尝试弄清楚要更新什么,并且什么也不更新。否则它会使用适当的refspec映射来翻译 refs / heads / foo 以查看要更新的内容。

      最后:



      1. 作为1的一个特例,如果git push推送本地非跟踪分支到远程分支机构(即如果没有相应的远程分支机构推送到本地分支机构),git push会创建与本地非跟踪分支相关联的远程跟踪分支,并将它们转换为本地跟踪分支?


      这个问题的部分对我来说仍然没有意义,但部分确实有意义。让我们考虑一个具体的例子,并且由于复杂的 fetch = 行,忽略三角形工作流程和奇怪的名称翻译,所以我们处理简单的 git push origin myname:theirname 命令。让我们进一步假设git版本是合理的最新的。

      再次,你的git,给定 git push origin myname:theirname ,首先将 myname 转换为原始SHA-1 ID。如果你 git push origin myname 你的git还会咨询你的 push.default 来填写他们的名字部分来自 myname 部分,但假设您给出了一个明确的名字 refs / heads / foo 例如。 (这也可以让你通过原始的SHA-1 ID进行推送,换句话说,它消除了大部分的复杂问题,并且现在让我们仅仅通过git-to-git推会话来担心。)



      你的git现在使用远程URL来打开他们的git。 (如果URL指向您自己的计算机上的另一个存储库,那么您的git会同时扮演您的git和他们的git角色,并且还会使用一组快捷方式,但是, )



      经过一些基本的协议握手之后,您的git会发送所有需要的对象,然后一次发送所有更新提议(从每个refspec给你的 git push ):

       请设置refs /头像/他们的名称为123456 ... 
      请将参考号/头像/别名设为987654 ...

      他们的git通过它的检查规则运行这些请求(包括内置的快速检查和任何接收端挂钩:预先接收和更新)来查看是否允许它们。然后,它会将新的SHA-1写入其引用中,并说是,已完成或拒绝更新并说不。



      您的git将所有这些回复并决定是否更新或创建 refs / remotes / origin / theirname 和/或 refs / remotes / origin / anothername 。 (请记住,我们假定远程名称为 origin ,并且您的git是近期的,等等)。对于任何是回复,您的git / em>更新或创建该名称;对于任何否,你的git不会。



      更新或创建完成就好像你的 git fetch 运行了 git update-ref (尽管它直接调用实际的更新,当然是使用fork / exec或spawn)。



      现在,完成这个完成后,你的git可以做的还有一件事,它取决于你是否提供了 -u (aka - set-upstream )标志为 git push (这当然取决于关于你的 git push 是否足够新有 -u 标志;当它出现时我会忘记它)。它还要求您的 push refspec(s)的左边最初解析为分支名称,而不是原始SHA-1。在这种情况下,你的git仍然会有所有的名字。



      如果你指定 -u ,那么 - 当推送成功时,你的git有效地运行 git branch --set-upstream-to 来设置或更改该分支的上游。 (当然,它只是在内部完成)。



      让我们把所有这些放在一个相当复杂的例子中。假设你有自己的本地分支 foo 和一个名为 origin 的远程,你可以这样做:

        $ git fetch origin 
      [输出剪切]
      $ git for-each-ref refs / remotes / origin#让我们看看他们的分支
      biguglysha1提交refs / remotes / origin / HEAD
      biguglysha1提交refs / remotes / origin / master
      #确认它们没有refs / heads / theirname
      $ git push -u origin foo:refs / heads / theirname
      [输出剪切,但假设它显示全部完成]

      完整的拼写, refs / heads / theirname ,是导致分支在这里成功创建所必需的(如果分支已经存在因为他们的git根据你提供的名字创建了分支,所以你可以使用短名称,但是我们有一个无聊的例子,而不是一个有趣的例子。)

      你的git是新的,你还没有设置怪异的名称映射,你现在有一个 refs / remotes / origin / theirname 。因为您指定了 -u ,您的本地分支 foo 现在将其上游设置为 origin /他们的名字也是 git branch -vv 现在会将 foo 显示为tracking origin / theirname 和最新的。



      这发生在两个部分:当他们的git接受设置 refs /头/他们的名字,你的git创建了 refs / remotes / origin / theirname ,并计算出 refs / remotes / origin /他们的名字需要经过 fetch = 地图;然后当你的git应用 -u 选项时,你的git将你的 branch.foo.remote 设置为 origin 和您的 branch.foo.merge refs / heads / theirname 。有趣的是,第二部分 - 应用 -u 标志 - 完全不需要map,因为 branch.foo.merge 设置为 refs / heads / theirname 。但是对于 git branch -vv 来显示 origin / theirname ,它必须通过地图。


      1. If I am correct, a remote-tracking branch can be created when cloning the remote repository. Are there other cases when a remote-tracking branch is created?

      2. If I am right, a remote-tracking branch is updated when fetching/pulling from the remote repository. Are there other cases when a remote-tracking branch is updated?

      3. As a special case of 2, when git push a local branch to the remote repository, if the local branch has an associated remote-tracking branch in the local repository (i.e. if the local branch is a local-tracking branch, defined in Version Control with Git by Loeliger 2ed), does git push update the remote-tracking branch , or the remote-tracking branch can be updated only indirectly from the remote repository by running git fetch or git pull after git push?

      4. As a special case of 1, if git push pushes local non-tracking branches to remote branches (i.e. if there is no corresponding remote branches to the local branches to be pushed), will git push create remote-tracking branches associated with the local non-tracking branches and turn them into local tracking ones?

      解决方案

      Let's take these three four :-) questions in order, more or less:

      1. ... a remote-tracking branch can be created when cloning the remote repository. Are there other cases when a remote-tracking branch is created?

      They are; and at least potentially yes, but let's get to that later.

      Specifically, when git clone is making an initial clone of another repository, it adds a fetch = configuration line for the remote. The line added depends on these two options:

      • --origin name: alters the name of the remote. Normally the name is just origin and the fetch configuration is fetch = +refs/heads/*:refs/remotes/origin/*, but if you change the name of the remote to, say, zerblatt, you get +refs/heads/*:refs/remotes/zerblatt/*.

      • --mirror: alters the fetch configuration to read fetch = +refs/*:refs/*. Note that in this case there are probably no remote-tracking branches after all, since "remote-tracking branches" is just a weakly abstracted way of saying "references in the refs/remotes/ name-space" and now we don't have any renaming going on. (If the repository being cloned presents its own remote-tracking branches—references in refs/remotes/—they will get copied and we will get remote-tracking branches. We might run git ls-remote to find out what references they have before we start cloning, in order to find out, although it's a little tricky since if we haven't started cloning, we don't have a repository in which to configure a remote so as to use git ls-remote. There is a method though!)

      Let's go on to:

      1. If I am right, a remote-tracking branch is updated when fetching/pulling from the remote repository. Are there other cases when a remote-tracking branch is updated?

      Yes: in particular a remote-tracking branch (which, again, is just a reference in the refs/remotes/ name-space) is updated automatically on at least some successful git push operations. Exactly which ones depends on your version of git, since push didn't always update them: the documentation noting this update first appeared in git 1.8.4 although the updates probably went in around git 1.7; and git 1.9 and later also update them in so-called "triangular workflows" (fetch from one remote, push to a different remote).


      Let me take a little break here and make a few more notes about remote-tracking branches.

      As we already noted, a remote-tracking branch is simply a reference whose full name begins with refs/remotes/. Git has a "plumbing" command, git update-ref, that you (or anyone or any script) can use to update any reference. For instance, suppose you've fetched from origin fairly recently, then added one commit to your own master (that's set with origin/master as its upstream) so that git status says you're "ahead 1". If you were to run:

      git update-ref refs/remotes/origin/master master
      

      and then run git status, your git would claim that you are now up-to-date. What happened is that you've told your git that "their" master (origin/master) points to the same commit as your own, even though you have not pushed your own commit yet. (If you do run this, you can simply run git fetch origin to fix refs/remotes/origin/master, or of course use git update-ref to fix it.)

      This exposes the underlying mechanism here: git simply writes, to refs/remotes/origin/master, the actual SHA-1 ID of the commit object your git saw when it talked to their (the remote's) git. There is a strong constraint on this: git can't put that SHA-1 ID in unless that SHA-1 ID corresponds to an actual object already stored in your own repository. In practice, git "feels" (and is) safe in writing that ID there after a successful fetch or push, since after a successful fetch, you must have the object, and to complete a push, you must have the object, and in both cases git has just seen that ID corresponding to some name on the given remote.

      This also shows how git status can say "ahead 1" in the first place: it simply counts the commits reachable from your master that are not reachable from your master's upstream. That is:

      ahead=$(git rev-list --count master@{u}..master)
      behind=$(git rev-list --count master..master@{u})
      echo "branch master is ahead $ahead and behind $behind"
      

      This information is as up-to-date (or out-of-date) as the last time the remote-tracking branch was properly updated.

      Let's also note, now, that git clone can be split up into several separate git commands. Let's assume you're cloning with neither --origin nor --mirror and that the url is simply $url (and that none of these steps fail):

      mkdir myclone && cd myclone && git init
      git remote add origin $url
      git fetch origin
      git checkout ...
      

      (exactly what to git checkout is a bit of a mystery; and the git fetch command can be skipped if we add -f to the git remote add line, but I intend to do something in between here for illustration purposes). What does each command do?

      • The mkdir + cd + git-init sequence creates a new empty, suitable-for-clone repository.
      • The git remote add line configures the remote origin to fetch from $url and adds a fetch = +refs/heads/*:refs/remotes/origin/* line.
      • The git fetch origin command then mostly-completes the cloning process (the missing bit is the final git checkout).

      Now, suppose that before we run git fetch origin, we run other git commands, such as git config --edit and mess with the fetch = line. We can set things up so that we don't get remote-tracking branches. We can create commits of our own, unrelated to what is on the actual remote, and use git update-ref to assign them to remote-tracking branches. We can run git ls-remote to find out what branches exist on the remote.

      None of these are particularly useful but they are all possible. (And if anyone has any good reason to do tricky branch-name-mapping things by creating a lot of fetch = lines, perhaps they are useful after all.)

      (What should we git checkout, on that last line? The answer depends on several things, only some of which we have direct control over. If you ran git clone with -b branch, that's the one we can handle the most easily: we should git checkout branch. If there's a refs/remotes/origin/branch we'll get a local branch branch that has its upstream set to origin/branch. If you did not specify a -b option, though, then what to check out, to emulate your git's git clone, depends on both your version of git, and the remote's version, as well as what we'd see from git ls-remote. Newer gits ask for and receive the branch name. Older gits take the [internal equivalent of the] ls-remote output and compare the SHA-1 the remote git shows for HEAD to the SHA-1 the remote git shows for each branch: if there's exactly one match, that's the branch; if there are multiple matches, pick one arbitrarily; if there are no matches at all, use master. If a newer git is talking to an older git that does not support the new "tell me the branch by name" option, the newer git falls back to the older method.)


      Back to your questions:

      1. As a special case of 2, when git push a local branch to the remote repository, if the local branch has an associated remote-tracking branch in the local repository (i.e. if the local branch is a local-tracking branch, defined in Version Control with Git by Loeliger 2ed), does git push update the remote-tracking branch, or the remote-tracking branch can be updated only indirectly from the remote repository by running git fetch or git pull after git push?

      I find this question confusing. There's no special casing involved here. At some point, we know that your git push has decided to send remote R a request that, in effect, says: "please set your refs/heads/foo to SHA-1 1234567890123456789012345678901234567890" (substitute in the correct refs/heads/ name and SHA-1 ID as needed). (When using --force-with-lease the request has more information in it, and in any case the request also carries the "force" flag. It's up to the remote to decide whether to obey the "force" flag. However, it's important to note here that the request delivers a raw SHA-1, and not the name of your branch in your local git repository. The remote git gets just his reference-name, and the SHA-1. What this means in practice is that the remote's pre- and post-receive and update hooks cannot see your branch names. [They don't get to see the force flag either, which I consider a minor bug, but that's another issue entirely.])

      Their git replies to this request with either a "yes, done" or "no: error: <details>" answer.

      Your git then has the option of treating the "yes, done" answer as sufficient to update your remote-tracking branch for remote R. (Of course a "no" reply means there is nothing to update.) It doesn't matter what local branch, if any, you're on, nor what local branches you have, nor whether any of them have upstreams set. This is in part because this same code allows you to do:

      git push origin 1234567890123456789012345678901234567890:refs/heads/foo
      

      to set their refs/heads/foo to that commit (assuming the commit ID is valid; your git will check your repository first, and deliver the commit to their git if necessary, as usual).

      The tricky bit for your git, in terms of doing a remote-tracking branch update, is figuring out what name your git should replace refs/heads/foo with. This is where the linear vs triangular work-flow stuff comes in, and where we must check which version of git you have. If you are using a triangular work-flow and your git is older than 1.9, your git doesn't know what to update, and updates nothing. If your git is older than about 1.7 or so, it never tries to figure out what to update, and updates nothing. Otherwise it uses the appropriate refspec mapping to translate refs/heads/foo to see what to update.

      Finally:

      1. As a special case of 1, if git push pushes local non-tracking branches to remote branches (i.e. if there is no corresponding remote branches to the local branches to be pushed), will git push create remote-tracking branches associated with the local non-tracking branches and turn them into local tracking ones?

      Pieces of this question still don't make sense to me, but pieces do make sense. Let's consider a concrete example, and ignore both triangular work-flows and weird name translations due to complicated multiple fetch = lines, so that we're dealing with simple git push origin myname:theirname commands. Let's further assume that the git version is reasonably up-to-date.

      Again, your git, given git push origin myname:theirname, starts by translating myname to a raw SHA-1 ID. If you git push origin myname your git also consults your push.default to fill in the theirname part from the myname part, but let's assume you've given an explicit name, refs/heads/foo for instance. (This also lets you push by raw SHA-1 ID. In other words, it takes most of the complications away, and leaves us just with the git-to-git "push" session to worry about, for now.)

      Your git now phones up their git using the URL for the remote. (If the URL refers to another repository on your own computer, your git plays both "your git" and "their git" roles, as it were, and uses a bunch of shortcuts as well, but let's just consider the over-the-Internet-phone case here.)

      After some basic protocol handshaking, your git sends over any objects needed, then sends over all your update proposals, all at once (from each refspec you gave to your git push):

      please set refs/heads/theirname to 123456...
      please set refs/heads/anothername to 987654...
      

      and so on.

      Their git runs these requests through its checking-rules (both the built-in fast-forward checks, and any receive-side hooks: pre-receive and update) to see whether to allow them. Then it either writes the new SHA-1s into its references and says "yes, done" or rejects the update and says "no".

      Your git takes all these replies and decides whether to update or create a refs/remotes/origin/theirname and/or refs/remotes/origin/anothername. (Remember, we're assuming the remote is named origin, and that your git is recent, etc.) For any "yes" reply, your git does update-or-create that name; for any "no", your git does not.

      The update-or-create is done as if your git fetch had run git update-ref (though it just invokes the actual update directly, rather than using fork/exec or spawn, of course).

      Now, once all of this is done, there's one more thing your git can do, and it depends on whether you supplied the -u (aka --set-upstream) flag to git push (which of course depends on whether your git push is new enough to have the -u flag; I forget when it appeared). It also requires that the left hand side of your push refspec(s) originally resolved to branch names, rather than raw SHA-1s. In this case your git will still have all the names.

      If you specify -u, then—as long as the push succeeds, your git effectively runs git branch --set-upstream-to to set or change the upstream for that branch. (Again, it just does this internally, of course.)

      Let's put all these together into a fairly complex example. Suppose you have your own local branch foo and a remote named origin, and you do:

      $ git fetch origin
      [output snipped]
      $ git for-each-ref refs/remotes/origin  # let's see their branches
      biguglysha1 commit  refs/remotes/origin/HEAD
      biguglysha1 commit  refs/remotes/origin/master
      # this confirms that they don't have a "refs/heads/theirname"
      $ git push -u origin foo:refs/heads/theirname
      [output snipped, but assume it says "all done"]
      

      The full spelling, refs/heads/theirname, is required to cause the branch to get created successfully here (if the branch already exists you can use the short name, but then we have a boring case instead of an interesting one).

      Because their git created the branch according to the name you supplied, and your git is new enough and you haven't set up weird name maps, you now have a refs/remotes/origin/theirname. Because you specified -u, your local branch foo now has its upstream set to origin/theirname as well. A git branch -vv will now show your foo as "tracking" origin/theirname and up-to-date.

      This happened in two parts: when their git accepted the request to set refs/heads/theirname, your git created refs/remotes/origin/theirname, and figuring out refs/remotes/origin/theirname required going through the fetch = map; and then when your git applied the -u option, your git set your branch.foo.remote to origin and your branch.foo.merge to refs/heads/theirname. Interestingly, the second part—applying the -u flag—does not need the map at all, since branch.foo.merge is set to refs/heads/theirname. But for git branch -vv to show origin/theirname, it has to go through the map.

      这篇关于何时创建和更新远程跟踪分支?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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