【问题标题】:in case of working within a branch, why does git push need additional arguments?如果在分支中工作,为什么 git push 需要额外的参数?
【发布时间】:2019-05-11 13:59:54
【问题描述】:

我做到了

git checkout -b NEW_BRANCH

到处都提到,为了将它推送到远程,必须告诉推送命令一些额外的信息

git push origin NEW_BRANCH

,或者必须将本地分支与远程分支相关联

git branch --set-upstream origin NEW_BRANCH

我不明白两者的必要性。换句话说,我不明白附加命令的效果?这些是什么?或者会发生什么,如果有人说

git 推送

? 在上述任一命令中,NEW_BRANCH 是指本地分支名称还是远程分支名称(如果有差异)?

【问题讨论】:

标签: git


【解决方案1】:

我不明白两者的必要性。换句话说,我不 了解附加命令的效果?它们是什么?

我假设您正在谈论这个命令:git push <remote-name> <branch-name>。你也可以git push

git 是一个分布式版本控制系统。因此,您可能拥有多个遥控器(甚至零个遥控器)。通俗地说,origin 是克隆后赋予遥控器的名称(您可以重命名或删除它,没关系)。希望这能说服您为什么(可能)需要指定遥控器。如果你有 7 个遥控器,git 无法知道你要推送到哪一个。 origin 是默认遥控器,如果你只是做git push

git 也不知道你要推送哪个分支。你可以有很多分支。因此,您可能想要推送一些而不是其他,这是合乎逻辑的,因此<branch-name> 参数的原因(技术上是refspec,它是分支的超集)。作为快捷方式,您可以指定 HEAD 作为您要推送的提交(HEAD 是指向当前提交的指针)。所以,你可以说git push origin HEAD,如果你有一个很长的分支名称,这特别方便。同样,git push 将默认推送当前分支,假设它具有匹配的上游分支。如果没有,您必须手动推送它 (git push origin HEAD),这将创建上游分支,然后准系统 git push 将从此为该分支工作,或者您也可以手动将其设置为上游分支 --set-upstream .

Mandatory docs link

HTH。

【讨论】:

    【解决方案2】:

    正确答案有多个部分,这就是为什么如此令人困惑的原因。为了正确理解这一点,让我们从定义一些术语开始:

    • remote 是一个简单的名称,例如 originupstream。这个名称让 Git 可以存储一个 URL——从技术上讲,一个或多个 URL,但通常只有一个——这样你就可以输入 origin 而不是输入 https://user@host.dom.ain/some/fairly/long/path/to/some/other/repo.git 或类似名称。

      Git 有一个内置的、或多或少标准的远程远程命名为origin,它由git clone 创建并自动记住您在运行git clone 时使用的URL。

    • referenceref 是您用来引用提交的东西,例如分支名称或标签名称,如 masterdevelop。引用有很长的形式:例如,master 实际上是 refs/heads/master。大多数时候你可以只使用短格式而不用担心这个,但是长格式就在那里,这是 Git 内部使用的,用于处理棘手的情况,比如你不小心制作了一个 tag @ 987654332@。 (不要故意这样做,但如果你做错了,长格式总是让你解决问题。)

    • refspec 本质上是一对由冒号: 字符分隔的引用。例如,master:master 是一个 refspec,refs/heads/develop:refs/heads/develop 也是。但这是 refspec 的一种更复杂的形式:在很多情况下,您可以去掉冒号和第二名,在这种情况下,它看起来就像一个引用。

    git push 需要的是,按顺序,一个 remote 后跟一个或多个 refspecs

    这反过来意味着你的问题的答案:

    git push origin NEW_BRANCH
    

    ... NEW_BRANCH 是指本地分支名称还是远程分支名称(如果有区别)?

    实际上有点复杂,因为NEW_BRANCH毕竟不是一个分支名称,它是一个refspec。它只是看起来像一个分支名称!

    git push 所做的是调用另一个 Git。另一个 Git 在 URL 上“活着”(或至少回答您的 Git 拨打的 Internet 电话),您的 Git 通过查找遥控器找到该 URL。然后两个 Git 进行对话,您的 Git 在对话中找出他们的 Git 有哪些提交,如果需要,提供他们的 Git new 提交,最后,让 他们的 Git 设置一些 他们的 分支名称,以记住在 您的 Git 存储库中找到的一些提交。 (此时,他们也有这些提交,如果他们以前没有的话,这要归功于中间的对话。)

    因此,您在此处给出的 NEW_BRANCH refspec 实际上是 both 名称。当您使用包含冒号的表单时,您可以使用两个不同的名称,甚至可以使用原始哈希 ID:

    git push origin master:somebranch
    

    让你的 Git 提供你的新提交,然后设置 他们的 somebranch 指向你的master 指向的相同 提交,或者:

    git push origin a123456:refs/heads/somebranch
    

    你的 Git 确保他们有提交 a123456...,然后设置 他们的 somebranch 指向那个特定的提交。1

    我不明白 [remote and refspec] 的必要性

    嗯,事实上,您通常不需要需要它们。您可能会认为这意味着总是,但由于多种历史原因,事实并非如此。

    首先,Git 并不总是有 remotes,所以你可以写出一个 URL 来代替远程名称。2 如果你没有'如果不使用远程或 URL,Git 会找出默认值(通常是 origin)。但是,如果您需要列出 refspec,则必须提供远程或 URL,因为远程或 URL 必须位于参数中的那个位置。

    其次,Git 使用默认使用一个过于热情的默认 refspec 一次推送多个分支。今天,它默认使用理智的 refspec 推送一个分支。这应该 - 并且确实! - 使它不需要 refspec,但只有在满足某些条件时才需要。而且,您可以更改这个默认值,使用push.default;如果你这样做了,那会改变你可以省略 refspec(s) 的条件,从而改变远程名称。

    使用今天默认的push.defaultsimple,Git 会自动找出并使用正确的远程和引用规范如果:

    1. 当前分支有一个上游集,并且
    2. 上游命名了远程上同名的分支。

    这里的遥控器可以是您的任何遥控器:如果分支xyz 的上游是foo/xyz,则遥控器是foofoo 上的分支是xyz,因此条件 1 和 2 都是遇到了,git push 会做正确的事。

    当您第一次创建新分支时,其上游设置(如果有)取决于您创建该分支的方式。使用git checkout -b <em>name</em> 会为您提供一个新分支name,默认情况下它有no 上游。使用git checkout --track <em>remote/name</em> 会为您提供一个新分支name,其中 remote/name 作为其上游,并且还有其他各种选项可以设置一些上游。


    1如果您使用这种形式,您通常必须拼出完整的参考名称。原因是当您使用缩短的名称时,例如 git push origin x234,Git 会扫描您的引用以找出,例如,x234分支 名称还是标签名称。这让你的 Git 告诉他们的 Git:设置你的 refs/heads/x234(分支)或 设置你的 refs/tags/x234(标签)。

    2在那些真正旧版本的 Git 中,您总是必须提供一个 URL。正如您可能想象的那样,这有点痛苦。这导致了几次实验,最终产生了 remote 的想法,并且一旦有一个名为 origin标准 遥控器,您就可以完全省略遥控器,只要你也可以省略所有的 refspecs。

    这些实验也仍然受到支持。您可以使用work:foo 加上insteadOf 条目将work: 映射到其中的主机名和可选路径。

    【讨论】:

      【解决方案3】:

      因为您还没有将本地分支与远程分支关联。

      请注意,远程和本地端的分支命名不需要是一对一的相同。

      在您当地的州,您的分支机构“链接”到上游分支机构。它只需要“建立那个链接”。

      要查看哪个分支的状态“链接”(跟踪)哪个远程分支,您可以使用(如果您的远程被称为origin):

      git remote show origin
      

      【讨论】:

        猜你喜欢
        • 2015-08-24
        • 1970-01-01
        • 2012-01-16
        • 2011-06-24
        • 2013-08-04
        • 1970-01-01
        • 2010-10-24
        • 2018-08-14
        • 1970-01-01
        相关资源
        最近更新 更多