【问题标题】:Git track a remote branch but push to a different branch?Git跟踪远程分支但推送到不同的分支?
【发布时间】:2016-06-29 22:03:12
【问题描述】:

假设我有一个名为“my-local-changes”的分支,它是一个本地分支,它是从一个名为“some-remote-branch”的分支创建的,它是一个远程分支。

我们还假设有一个名为“develop”的第三个分支,它是从多个分支中提取代码的远程分支(“some-remote-branch”就是其中之一,我还有一个名为“跟踪远程开发分支的develop')

我的问题是如何设置“my-local-changes”来跟踪“develop”分支,但推送到“some-remote-branch”分支?

对于那些好奇的人,至于我为什么要这样做,我希望能够运行 git status 并查看我是否落后于“开发”,而不必切换到该分支,并且仍然能够轻松地推送到“某个远程分支”

我目前的流程如下(我也希望有任何改进的建议)

git checkout -b my-local-branch some-remote-branch

(进行一些更改并添加它们)

git fetch origin 
git checkout develop
git status

(执行此操作以查看是否需要合并开发中的任何更改,如果不运行)

git push origin my-local-branch some-remote-branch

【问题讨论】:

    标签: git bitbucket


    【解决方案1】:

    (不知道为什么这个问题被否决了,1而且你几乎已经自己回答了......)

    您快到了:只需将push.default 配置为simplenothing,以便您必须为此案例指定推送目标,然后对于您的最终命令,使用:

    git push origin my-local-branch:some-remote-branch
    

    其工作方式是git pushorigin(遥控器的名称)之后采用一系列refspecs。 refspec 不是很复杂:它只是一对名称,例如 master:masterdevelop:developdevelop:foo,可以选择带有前导加号 +,并且可以选择省略第一个或第二个名称:@ 987654331@或develop

    Refspecs 会变得稍微复杂一点,因为它们在git fetchgit push 中的工作方式不同,如果你省略了这两个名称之一。如果您每次都使用这两个名称,它们将保持简单:左侧的名称是 source 存储库上的名称,右侧的名称是 destination 上的名称>。对于fetch,源是远程,目标是您自己的存储库。对于push,源是您的存储库,目标是远程。

    省略源名称仅适用于push,在这种情况下,它意味着删除。因此git push origin :foo 表示删除远程origin 上的foo。 (这不是你想要的,所以要避免。)

    省略目标名称适用于fetchpush,但对它们来说意味着不同的东西。让我们在这里忽略fetch。对于push,这意味着在本地和远程使用相同的名称。既然您在此处使用它,请不要在此处使用它。 (或者,如果您确实需要它,请继续使用它。)

    前导 + 符号(如果存在)与 --force 的含义相同。 (实际上--force 只是在所有内容上添加+。)

    如果您运行 git push origingit push(甚至没有 remote 参数),Git 会查找 push.default 以查看要推送的内容。将其设置为nothing 意味着只是失败/错误输出,所以我必须输入一个参考规范。将其设置为simple 意味着只将一个分支,即当前分支推送到当前分支的上游,但还要求上游名称匹配。由于my-local-branchsome-remote-branch 不匹配,因此对于您的本地分支foo 正在跟踪远程跟踪分支origin/develop 的情况将失败:名称foo 和@987654360 @不匹配。

    无论哪种方式,Git 都会强制您为此推送输入 refspec。

    使用nothing 配置,Git 将强制您为每个 推送输入一个参考规范。 (我已经使用过它并且它有效,但它不是非常方便。)使用simple 配置,Git 将允许您将develop 轻松推送到上游develop,并允许您推送您的@987654365 @ 到上游develop(或上游jazzy,或除foo 之外的任何其他名称),但不会将foo 推送到foo,因为这不是它定义的上游。 (我用过这个,效果更好。)

    从 Git 2.0 版开始,simple 是默认配置。因此,如果您拥有 Git 2.0 版或更高版本,您就可以开始使用了。如果没有,请查看您是否可以升级您的 Git 版本,但 push.default 可早于 Git 版本 1.6 进行配置。 (那么,我不确定它可以采用什么值。我认为,如果不是更早的话,当前的 5 组值可以追溯到 1.7.11。)

    为了完整起见,其他三个可能的值是:currentupstreammatchingcurrent 值表示使用当前分支的名称:git push origin $branch:$branch 其中$branch 是当前分支。 upstream 值表示使用当前分支的上游名称:git push origin $branch:$merge,其中$merge 来自git config --get branch.$branch.merge

    matching 值是最难描述的,并且是 Git 2.0 版之前的默认值:这意味着 获取远程上每个分支的列表,并将它们的名称与我们的本地分支名称匹配,并且然后将我们所有的本地分支整体推送到远程上同名的分支,只要两个名称匹配。这不是一个非常安全的设置,尽管只要你不这样做使用--force,它实际上在实践中效果很好,这就是它可以使用这么多年的原因。

    旁注:术语

    Git 的术语有点乱。

    • local 分支(或只是“分支”或“分支名称”),例如 master,是 refs/heads/ 命名空间中的名称。它指向一个提交 ID。当您在该分支上进行新提交时,Git 会读取提交 ID,使用该 ID 作为新提交的父级进行新提交,然后将新提交的 ID 写入分支名称,以便分支现在指向新的提交(它又指向前一个分支提示,依此类推)。

      您可以git checkout 一个本地分支,这会将您置于“分支上”,例如,git status 表示On branch master。正如我上面刚刚提到的,这会设置好新的提交来推进分支。

    • origin/master 这样的远程跟踪分支refs/remotes/ 命名空间中的名称。在refs/remotes/ 之后,我们找到远程本身的名称origin,然后是另一个斜线,最后是在该远程上看到的分支名称(当然没有refs/heads/)。这些名称存储在本地,在您自己的存储库中:它们实际上根本不是远程的。当您的 Git 通过git fetch 和(在更有限的范围内)通过git push 联系远程时,它们只是自动更新

      您可以git checkout 远程跟踪分支,但如果这样做,git checkout 会将您置于“分离 HEAD”模式,因此 git statusgit branch 声称您不在任何分支上(或在“无分支”或类似情况下,有时使用“分离的 HEAD”措辞)。当这种情况发生时,你实际上是在(单一的,特殊的)anonymous 分支上。当您回到正常分支时,您在匿名分支上所做的任何工作最终都会消失。 (因此,如果您想保留这项工作,请设置一个名称,使其不再是匿名的 - 或使用 git checkout 回到常规分支,然后再执行该工作。)

    • 本地分支可以跟踪另一个分支(本地远程)。当本地分支 B 正在跟踪另一个分支 U 时,Git 将其称为本地分支的“上游”。这个上游由两部分组成:远程名称,如origin,以及远程分支的名称,如master。要将本地分支跟踪为分支 B 的上游,Git 只需将远程设置为 .

      因此本地分支 B 正在跟踪上游 U 是否配置了这两个项目。 U 本身通常是一个远程跟踪分支,它是一个本地实体(refs/remotes/ 名称空间名称之一)。您必须git fetchgit push 才能更新远程跟踪分支,之后git statusgit branch -vv 将报告跟踪远程跟踪分支的本地分支领先和/或落后他们的同行。

      本地分支 B 可以改为跟踪另一个本地分支作为其上游。在这种情况下,由于所有内容都是本地更新的,git statusgit branch -vv 将是最新的,不需要任何 git fetch

      本地分支B当然不需要跟踪任何东西。命令git branch --set-upstream-to <em>upstream</em>git branch --unset-upstream 将设置或取消设置当前分支的上游。您还可以使用 git config 设置、更改和检查上游的两个单独部分(branch.$branch.remotebranch.$branch.merge 部分),尽管使用 git branch 通常更好更方便。


    1可能是因为 Git 2.0 默认 push.default

    【讨论】:

      猜你喜欢
      • 2018-02-12
      • 2014-02-04
      • 2016-02-22
      • 2011-01-09
      • 2020-09-26
      • 2011-09-10
      • 2016-07-08
      • 2020-05-22
      • 2010-10-05
      相关资源
      最近更新 更多