[英]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.default
以simple
或nothing
,所以,你必须指定此情况下,推目标,然后为你的最后一个命令,使用:
git push origin my-local-branch:some-remote-branch
它的工作方式是git push
在origin
(远程名称)之后接受一系列refspecs 。 refspec并不是很复杂:它只是一对名称,例如master:master
或develop:develop
或develop:foo
,可以选择使用前导加号+
,也可以省略名字或第二个名称:foo
或develop
。
Refspec有点复杂,因为当您忽略两个名称之一时,它们在git fetch
和git push
工作方式有所不同。 如果您每次都使用这两个名称,它们将保持简单:左侧的名称是源存储库中的名称,右侧的名称是目标存储库中的名称。 对于fetch
,源是远程,目标是您自己的存储库。 对于push
,源是您的存储库,目标是远程。
省略源名称仅适用于push
,在这种情况下,这意味着delete 。 因此git push origin :foo
意味着删除远程origin
上的foo
。 (那不是您想要的,所以避免这种情况。)
省略目的地名称既可用于fetch
也可用于push
但对它们意味着不同的含义。 让我们在这里忽略fetch
。 使用push
意味着在本地和远程使用相同的名称 。 既然你不想在这里,这里不使用它。 (或者,对于您确实需要的情况,请继续使用。)
前导+
符号(如果存在)与--force
相同。 (实际上--force
只是在所有内容上加上+
。)
如果运行git push origin
或git push
(甚至没有remote
参数),Git都会查找push.default
以查看要推送的内容。 将其设置为nothing
意思只是失败/错误了,所以,我必须输入一个的Refspec。 将其设置为simple
意味着仅将一个分支(当前分支)推送到当前分支的上游,但还需要上游名称match 。 由于my-local-branch
和some-remote-branch
不匹配,因此这将因您本地分支foo
正在跟踪远程跟踪分支origin/develop
的情况而失败:名称foo
和develop
不匹配。
无论哪种方式,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。)
为了完整起见,其他三个可能的值是: current
, upstream
和matching
。 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 status
和git branch
声明您不在任何分支上(或位于“无分支”或类似,有时使用“分离式HEAD”措词)。 发生这种情况时,您实际上位于(单个,特殊) 匿名分支上。 当您回到普通分支时,您在匿名分支上所做的任何工作最终都会消失。 (因此,如果您想保留工作,请设置一个名称,以使其不再是匿名的;或者在执行该工作之前,使用git checkout
返回常规分支。)
本地分支机构可以跟踪另一个分支机构(本地或远程)。 当本地分支B跟踪另一个分支U时 ,Git将此称为本地分支的“上游”。 此上游由两部分组成:远程服务器的名称(如origin
)和在远程服务器上看到的分支的名称(如master
。 为了跟踪本地分支作为分支B的上游,Git只是将远程设置为.
代替。
因此,如果本地分支B配置了这两项,则它正在跟踪上游U。 U本身通常是一个远程跟踪分支,它是一个本地实体(这些refs/remotes/
名称空间名称之一)。 您必须git fetch
或git push
来更新远程跟踪分支,此后git status
和git branch -vv
将报告正在跟踪远程跟踪分支的本地分支,它们位于对应分支的前面和/或后面。 。
本地分支B可以代替地跟踪另一个本地分支作为其上游。 在这种情况下,由于所有内容都是本地更新的,因此git status
和git branch -vv
将是最新的,而无需任何git fetch
。
当然,本地分支机构B无需跟踪任何内容。 git branch --set-upstream-to upstream
和git branch --unset-upstream
将设置或取消当前分支的上游。 您还可以使用git config
来设置,更改和检查上游的两个独立部分( branch.$branch.remote
和branch.$branch.merge
部分),尽管使用git branch
通常会更好,更方便。
1可能是因为Git 2.0的默认push.default
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.