Git跟踪一个远程分支,但是推送到另一个分支吗? [英] Git track a remote branch but push to a different branch?
问题描述
假设我有一个名为"my-local-changes"的分支,这是一个本地分支,它是由一个名为"some-remote-branch"的分支(它是一个远程分支)创建的.
Lets assume I have a branch called 'my-local-changes', which is a local branch, that was created from a branch called 'some-remote-branch', which is a remote branch.
我们还假设有一个名为"develop"的第三个分支,这是将代码从多个分支拉入的远程分支("some-remote-branch"就是其中之一,我也有一个名为开发"(跟踪远程开发分支)
Let's also assume there is a third branch called 'develop', which is the remote branch where code is pulled into from multiple branches ('some-remote-branch' is one of them, I also have a local branch called 'develop' that tracks the remote develop branch)
我的问题是我该如何设置"my-local-changes"来跟踪"develop"分支,而将其推送到"some-remote-branch"分支?
对于那些好奇的人,关于我为什么要这样做,我希望能够运行git status并查看我是否落后于"develop",而不必切换到该分支,并且仍然能够轻松地推送到远程分支"
For those curious, as to why I want to do this, I would like to be able to run git status and see if I am behind 'develop' while not having to switch to that branch, and easily still be able to push to 'some-remote-branch'
我当前的流程如下(我也希望对此有所改进的任何建议)
My current process is as follows (I'd love any suggestions for improving this as well)
git checkout -b my-local-branch some-remote-branch
(进行一些更改并将其添加)
(make some changes and add them)
git fetch origin
git checkout develop
git status
(执行此操作以查看是否需要合并开发中的任何更改,如果未运行的话)
(do this to see if any changes on develop that I need to merge, if not run)
git push origin my-local-branch some-remote-branch
推荐答案
(不确定问题为何被否决, 1 ,您几乎还是自己回答了这个问题...)
(Not sure why the question is downvoted,1 and you have almost answered it yourself anyway...)
您快到了:只需将push.default
配置为simple
或nothing
,以便必须为此情况指定推送目标,然后对于最终命令使用:
You are nearly there: simply configure push.default
to simple
or nothing
, so that you must specify the push target for this case, and then for your final command, use:
git push origin my-local-branch:some-remote-branch
此方法的工作方式是git push
在origin
(遥控器的名称)之后采用一系列 refspecs . refspec并不是很复杂:它只是一对名称,例如master:master
或develop:develop
或develop:foo
,可以选择使用前导加号+
,还可以选择省略名字或名字::foo
或develop
.
The way this works is that git push
takes, after origin
(the name of the remote), a series of refspecs. A refspec is not very complicated: it's just a pair of names, like master:master
, or develop:develop
, or develop:foo
, optionally with a leading plus sign +
, and optionally omitting either the first or second name: :foo
or develop
.
Refspec有点复杂,因为当您忽略两个名称之一时,它们在git fetch
和git push
中的工作方式有所不同.如果您每次都使用这两个名称,它们将保持简单:左侧的名称是 source 存储库中的名称,右侧的名称是目的地上的名称>.对于fetch
,源是远程,目标是您自己的存储库.对于push
,源是您的存储库,目标是远程.
Refspecs get slightly complicated in that they work differently in git fetch
and git push
, when you leave out one of the two names. If you use both names each time, they stay simple: the name on the left is the name on the source repository, and the name on the right is the name on the destination. For fetch
, the source is the remote and the destination is your own repository. For push
, the source is your repository and the destination is the remote.
省略源名称仅适用于push
,在这种情况下,这意味着删除.因此,git push origin :foo
表示删除远程origin
上的foo
. (那不是您想要的,所以请避免.)
Leaving out the source name only works with push
, and in this case, it means delete. Hence git push origin :foo
means delete foo
on remote origin
. (That's not what you want, so avoid that.)
省略目的地名称对fetch
和push
均适用,但对它们意味着不同的含义.让我们在这里忽略fetch
.对于push
,这意味着在本地和远程上都使用相同的名称.由于您不想在这里想要它,所以不要在这里使用它. (或者,对于您要做想要的情况,请继续使用它.)
Leaving out the destination name works with both fetch
and push
but means different things to them. Let's just ignore fetch
here. With push
, it means use the same name on both local and remote. Since you don't want that here, don't use it here. (Or, for those cases where you do want it, go ahead and use it.)
前导+
符号(如果存在)的含义与--force
相同. (实际上,--force
只会在所有内容上添加+
.)
The leading +
sign, if present, means the same as --force
. (In fact --force
just adds the +
on everything.)
如果运行git push origin
或git push
(甚至没有 remote
参数),Git都会查找push.default
以查看要推送的内容.将其设置为nothing
意味着只是失败/错误输出,因此我必须输入refspec .将其设置为simple
意味着仅将一个分支(当前分支)推送到当前分支的上游,但还要求上游名称匹配.由于my-local-branch
和some-remote-branch
不匹配,对于您的本地分支foo
正在跟踪远程跟踪分支origin/develop
的情况,这将失败:名称foo
和
If you run git push origin
, or git push
(without even a remote
argument), Git looks up push.default
to see what to push. Setting it to nothing
means just fail / error-out, so that I have to type in a refspec. Setting it to simple
means push just one branch, the current branch, to the current branch's upstream, but also require that the upstream name match. Since my-local-branch
and some-remote-branch
don't match, this will fail for your case of local branch foo
is tracking remote-tracking branch origin/develop
: the names foo
and develop
do not match.
无论哪种方式,Git都会强制您为此推送输入参考规范.
Either way, Git will force you to enter a refspec for this push.
使用nothing
配置,Git将强制您输入每次推送的参考规范. (我已经使用了它,并且它可以工作,但是并不是很方便.)使用simple
配置,Git将允许您轻松地将develop
推入上游develop
,并且将允许您推入develop
(或上游jazzy
或除foo
以外的任何其他名称),但不会将foo
推入foo
,因为这不是其定义的上游. (我已经用过了,效果更好.)
With the nothing
configuration, Git will force you to enter a refspec for every push. (I have used this and it works, but it's not terribly convenient.) With the simple
configuration, Git will allow you to push your develop
to the upstream develop
easily, and will allow you to push your foo
to an upstream develop
(or an upstream jazzy
, or any other name but foo
) explicitly, but won't push foo
to foo
since that's not its defined upstream. (I have used this and it works better.)
从Git 2.0版开始,simple
是默认配置.因此,如果您拥有Git 2.0版或更高版本,则已经可以使用了.如果不是,请查看是否可以升级您的Git版本,但是push.default
可以在Git 1.6版之前进行配置. (然后,我不确定会采用什么值.我认为,如果不是更早的话,当前的5组值会回到1.7.11.)
As of Git version 2.0, simple
is the default configuration. So if you have Git version 2.0 or later, you are already good to go. If not, see if you can upgrade your Git version, but push.default
is configurable as far back as Git version 1.6. (I'm not sure what values it could take on, then. The current set-of-5 values goes back to 1.7.11 if not earlier, I think.)
为完整性起见,其他三个可能的值是:current
,upstream
和matching
. current
值表示使用当前分支的名称:git push origin $branch:$branch
其中$branch
是当前分支. upstream
值表示使用当前分支的上游名称:git push origin $branch:$merge
,其中$merge
来自git config --get branch.$branch.merge
.
For completeness, the other three possible values are: current
, upstream
, and matching
. The current
value means use the current branch's name: git push origin $branch:$branch
where $branch
is the current branch. The upstream
value means use the current branch's upstream name: git push origin $branch:$merge
, where $merge
is from git config --get branch.$branch.merge
.
matching
值是最难描述的,它是Git 2.0版之前的默认值:这意味着获取遥控器上每个分支的列表,并匹配其名称和我们的本地分支名称,以及然后将我们所有的本地分支进行en-masse推送到遥控器上相同名称的分支,无论这两个名称是否匹配.这不是一个非常安全的设置,尽管只要您不这样做即可.使用--force
,实际上在实践中效果很好,这就是为什么它可以使用很多年的原因.
The matching
value is the hardest to describe, and was the default before Git version 2.0: it means get a list of every branch on the remote, and match up their names and our local branch names, and then do an en-masse push of all of our local branches to the branch of the same name on the remote, wherever the two names match up. This is not a very safe setting, although as long as you do not use --force
, it actually works pretty well in practice, which is why it was usable for so many years.
Git的术语有点混乱.
Git's terminology is kind of a mess.
-
一个 local 分支(或简称为一个分支"或一个分支名称"),如
master
,是refs/heads/
命名空间中的名称.它指向一个提交ID.当您在该分支上进行新提交时,Git会读取提交ID,以该ID作为新提交的父对象进行新提交,然后将新提交的ID写入分支名称,以便分支现在指向新的提交(依次指向上一个分支提示,依此类推).
A local branch (or just "a branch" or "a branch name"), like
master
, is a name in therefs/heads/
name-space. It points to a commit ID. When you make a new commit while on that branch, Git reads the commit ID, makes the new commit with that ID as the new commit's parent, and then writes the new commit's ID into the branch-name, so that the branch now points to the new commit (which in turns points to the previous branch-tip, and so on).
您可以git checkout
本地分支,这会将您置于分支上",例如,git status
说On branch master
.如上所述,这可以进行设置,以便新的提交使分支前进.
You can git checkout
a local branch, which puts you on "on the branch", so that git status
says On branch master
for instance. This sets things up so that new commits advance the branch, as I just noted above.
像origin/master
这样的远程跟踪分支是refs/remotes/
命名空间中的名称.在refs/remotes/
之后,我们找到遥控器本身的名称origin
,然后是另一个斜杠,最后是该遥控器上看到的分支的名称(当然没有cc64).这些名称存储在本地的自己的存储库中:它们实际上根本不是远程的.当您的Git通过git fetch
和(在更有限的范围内)通过git push
与遥控器联系时,它们只是自动更新.
A remote-tracking branch like origin/master
is a name in the refs/remotes/
name-space. After refs/remotes/
we find the name of the remote itself, origin
, then another slash, and finally the name of the branch as seen on that remote (sans refs/heads/
of course). These names are stored locally, in your own repository: they're not actually remote at all. They are just automatically updated when your Git contacts the remote, through git fetch
and (to a more limited extent) through git push
.
您可以git checkout
远程跟踪分支,但是如果这样做,git checkout
会将您置于分离头"模式,因此git status
和git branch
声称您不在任何分支上(或位于无分支"或类似位置,有时使用分离的HEAD"措词).发生这种情况时,您实际上位于(单个,特殊)匿名分支.当您回到普通分支时,您在匿名分支上所做的任何工作最终都会消失. (因此,如果您想保留工作,请设置一个名称,以使其不再是匿名的,或者在执行该工作之前,使用git checkout
返回常规分支.)
You can git checkout
a remote-tracking branch, but if you do, git checkout
puts you in "detached HEAD" mode, so that git status
and git branch
claim you're not on any branch (or are on "no branch" or similar, sometimes using the "detached HEAD" phrasing). When this happens you are actually on the (single, special) anonymous branch. When you get back on a normal branch, any work you did on the anonymous branch will eventually fade away. (So if you want to keep the work, set up a name, so that it's not anonymous anymore—or use git checkout
to get back on a regular branch, before you do that work.)
本地分支可以跟踪另一个分支(本地或远程).当本地分支 B 跟踪另一个分支 U 时,Git将此称为本地分支的上游".此上游由两部分组成:遥控器的名称(如origin
)和在遥控器上看到的分支的名称(如master
).为了将本地分支作为分支 B 的上游,Git只是将远程设置为.
.
A local branch can track another branch (local or remote). When local branch B is tracking another branch U, Git calls this the "upstream" of the local branch. This upstream is composed of two parts: the name of the remote, like origin
, and the name of the branch as seen on the remote, like master
. To track a local branch as your upstream for branch B, Git just sets the remote to .
instead.
因此,本地分支机构 B 如果已配置了这两项,则会跟踪上游 U . U 本身通常是一个远程跟踪分支,它是一个本地实体(这些refs/remotes/
名称空间名称之一).您必须git fetch
或git push
来更新远程跟踪分支,然后,git status
和git branch -vv
将报告正在跟踪远程跟踪分支的本地分支,位于前面和/或后面.他们的同行.
Hence local branch B is tracking upstream U if it has these two items configured. U is itself normally a remote-tracking branch, which is a local entity (one of those refs/remotes/
name-space names). You must git fetch
or git push
to get the remote-tracking branch(es) updated, after which git status
and git branch -vv
will report local branches that are tracking the remote-tracking branches, as being ahead and/or behind their counterparts.
本地分支 B 可以代替地跟踪另一个本地分支作为其上游.在这种情况下,由于所有内容都是本地更新的,因此git status
和git branch -vv
将是最新的,而无需任何git fetch
.
Local branch B can instead track another local branch as its upstream. In this case, since everything is locally-updated, git status
and git branch -vv
will be up-to-date without any git fetch
needed.
本地分支 B 当然不需要跟踪任何内容.命令git branch --set-upstream-to upstream
和git branch --unset-upstream
将设置或取消设置当前分支的上游.您也可以使用git config
来设置,更改和检查上游的两个单独部分(branch.$branch.remote
和branch.$branch.merge
部分),尽管使用git branch
通常会更好,更方便.
A local branch B need not track anything, of course. The commands git branch --set-upstream-to upstream
and git branch --unset-upstream
will set or unset the upstream of the current branch. You can also set, change, and examine the two individual parts of the upstream (the branch.$branch.remote
and the branch.$branch.merge
parts) using git config
, although using git branch
is usually nicer and more convenient.
1 也许是因为Git 2.0默认值push.default
导致了投票失败.
1Perhaps the downvote is because of the Git 2.0 default push.default
.
这篇关于Git跟踪一个远程分支,但是推送到另一个分支吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!