繁体   English   中英

Git跟踪一个远程分支,但是推送到另一个分支?

[英]Git track a remote branch but push to a different branch?

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

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

我的问题是如何设置“我的本地更改”来跟踪“开发”分支,而又将其推到“远程分支”分支?

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

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

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

(不知道为什么这个问题被否决了, 1反正您几乎已经回答了这个问题...)

就快成功了:只需配置push.defaultsimplenothing ,所以,你必须指定此情况下,推目标,然后为你的最后一个命令,使用:

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

它的工作方式是git pushorigin (远程名称)之后接受一系列refspecs refspec并不是很复杂:它只是一对名称,例如master:masterdevelop:developdevelop:foo ,可以选择使用前导加号+ ,也可以省略名字或第二个名称:foodevelop

Refspec有点复杂,因为当您忽略两个名称之一时,它们在git fetchgit push工作方式有所不同。 如果您每次都使用这两个名称,它们将保持简单:左侧的名称是存储库中的名称,右侧的名称是目标存储库中的名称。 对于fetch ,源是远程,目标是您自己的存储库。 对于push ,源是您的存储库,目标是远程。

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

省略目的地名称既可用于fetch也可用于push但对它们意味着不同的含义。 让我们在这里忽略fetch 使用push意味着在本地和远程使用相同的名称 既然你不想在这里,这里不使用它。 (或者,对于您确实需要的情况,请继续使用。)

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

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

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

使用nothing配置时,Git将强制您为每次推送输入一个refspec。 (我用这个和它的作品,但它并不十分方便。)通过simple的配置,Git会允许你把你的develop向上游develop容易,并允许您将推动foo到上游develop (或上游jazzy ,或除foo任何其他名称),但不会将foo推送到foo因为这不是其上游定义的。 (我已经用过了,效果更好。)

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

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

matching值是最难描述的,并且是Git 2.0版之前的默认值:这意味着获取远程服务器上每个分支的列表,并匹配其名称和我们的本地分支名称,然后进行en-masse push我们所有的本地分支都将转移到远程站点上具有相同名称的分支,无论这两个名称是否匹配。 这不是一个非常安全的设置,尽管只要不使用--force ,它实际上在实践中就可以很好地工作,这就是为什么它可以使用很多年的原因。

旁注:术语

Git的术语有点混乱。

  • 本地 master (或“分支”或“分支名称”),例如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会将您置于“分离头”模式,以便git statusgit branch声明您不在任何分支上(或位于“无分支”或类似,有时使用“分离式HEAD”措词)。 发生这种情况时,您实际上位于(单个,特殊) 匿名分支上。 当您回到普通分支时,您在匿名分支上所做的任何工作最终都会消失。 (因此,如果您想保留工作,请设置一个名称,以使其不再是匿名的;或者在执行该工作之前,使用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 upstreamgit branch --unset-upstream将设置或取消当前分支的上游。 您还可以使用git config来设置,更改和检查上游的两个独立部分( branch.$branch.remotebranch.$branch.merge部分),尽管使用git branch通常会更好,更方便。


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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM