如何轻松地将本地 Git 分支推送到具有不同名称的远程?
总结:
以下是您通常需要的关键命令的简短摘要:
# push from your local `branch2` to a remote `branch1` (push to a branch with
# a different name) on the remote named `origin`
git push -u origin branch2:branch1
# pull from a remote branch `branch1` into your currently-checked-out branch
# (which could have a different name--ex: `branch2`)
git pull origin branch1
# Set your upstream to something new in case you want to change it; ex: set your
# currently-checked-out branch (perhaps `branch2`) to track `branch1` on the
# remote named `origin`
git branch -u origin/branch1
# Unset your upstream
git branch --unset-upstream
# See what your upstream is currently set to
git branch -vv
细节:推送到另一个分支,从另一个分支拉取,设置和取消设置上游分支以跟踪
这里有太多不完整和部分的答案,这给我留下了很多问题和很多不足之处。因此,经过大量的努力、研究和试验,我尝试提供一个完整的解决方案。
1。从本地分支推送到具有不同名称的远程分支
要从本地 branch2 推送到远程 branch1,您必须像这样指定两个分支:
# Push from local `branch2` to remote `branch1`
git push origin branch2:branch1
# General form: push from local `from_branch` to remote `to_branch`.
# - Watch out!: see also the additional explanations and NB note below!
git push <remote> <from_branch>[:to_branch]
但是请注意,我在上面一般形式中写的方括号表示:to_branch 部分是可选的。我的意思是从一个名称的本地分支推送到另一个名称的远程分支,这部分不是可选的,但是,作为一个通用的 git 命令,如果你不包含:to_branch,该命令将运行部分,这意味着它在这个意义上是可选的。但是,它可能会产生意想不到的结果!看看这个命令,例如:
# (push to a remote branch with the **same name** as the local branch)
# Reduced **and confusing** form: this pushes from local `branch2` (even if you
# don't currently have it checked-out!) to remote `branch2`.
git checkout branch3
git push origin branch2 # Push from local branch2 to remote branch2
您可能当前已签出本地branch3,并认为git push origin branch2 会将您本地的branch3 推送到远程branch2,因为您的系统上当前已签出branch3,但是这不是会发生的!相反,git push origin branch2 会将您的本地 branch2 再次推送到您的远程 branch2,即使您当前没有 branch2 已签出! 因此,git push origin branch2 是一个等效的短- 这个的手:
# These 2 commands are **exactly identical**! The 1st cmd is the short form
# of the 2nd.
git push origin branch2 # Push from local branch2 to remote branch2
git push origin branch2:branch2 # Push from local branch2 to remote branch2
如果您认为它会从您当前签出的分支推送,那么上述 cmd 的简短形式会产生非常混乱的行为。以下是总结上述行为的 Nota bene 说明:
NB:在一般形式git push <remote> <from_branch>[:to_branch]中,如果你没有用:to_branch指定远程TO分支,则假定它与你的本地FROM分支同名,from_branch,on remote!这意味着如果您只键入git push origin branch2 而不是git push origin some_other_branch:branch2,它会从您的本地branch2 推送到branch2 的远程副本,即使您在运行时没有branch2 在本地签出命令!如果您认为输入git push origin branch2 刚刚告诉您当前签出的分支some_other_branch 推送到远程的branch2 而不是本地的branch2,这可能会非常令人困惑被推送到远程branch2。
通用表单 (git push <remote> <from_branch>[:to_branch]) 的文档很难找到,但实际上可以在靠近顶部的 man git push 页面中找到,位于“"<refspec>...”部分下方:
<refspec> 参数的格式是可选的加上+,后跟源对象<src>,后跟冒号:,后跟目标引用<dst>。
然后:
:<dst> 部分可以省略——这样的推送将更新一个引用,<src> 通常会在命令行上没有任何<refspec> 的情况下更新。
我认为此文档不直观且很难理解,但是,如果没有一些示例和我上面的解释。
[BETTER FORM OF git push]你也可以在推送的同时设置上游分支:
# Push from local `branch2` to the remote `branch1`, while also at the same time
# setting `branch2` to track `origin/branch1` as the upstream
git push -u origin branch2:branch1
# OR (same thing)
git push --set-upstream origin branch2:branch1
# General form
git push -u <remote> <from_branch>[:to_branch]
作为上述命令输出的一部分,您应该看到:
Branch 'branch2' set up to track remote branch 'branch1' from 'origin'.
为了让那里发生的事情变得明显,请知道上面的两个命令中的任何一个都等效于这些 两个 单独的命令:
git push origin branch2:branch1
git branch -u origin/branch1
现在,要查看您分支的上游分支当前设置的内容,请运行 double-verbose (-vv) git branch cmd:
git branch -vv
样本输出:
这里可以看到上游分支是origin/master,也就是说远程上的master分支名为origin:
* master b2f0466 [origin/master] c/array_filter_and_remove_element.c: add O(n) in-place solution
注意事项:
-
-vv 上面的意思是“双重冗长”。这意味着它将打印git branch,不仅是冗长的,而且是双倍的,或者更冗长的。现在打印的“额外详细”内容包括方括号中的上游分支,如上所示:[origin/matser]。
- 您可以使用
git remote -v 查看所有遥控器。 origin 是上面示例中显示的遥控器。
2。从具有不同名称的远程分支拉到本地分支
[如果您已经有分支 branch2 在本地签出,推荐使用!] 到 在名为 origin 的遥控器上拉出 branch1,到 branch2,您必须指定要从中提取的远程分支,如下所示:
# THIS ASSUMES YOU ARE ALREADY CHECKED-OUT ON BRANCH `branch2`!
git pull origin branch1
# General form
git pull <remote> [from_branch]
你也可以指定两个分支,但是我不完全确定这种情况下有什么区别(如果你知道的话,请在这里帮助我):
git pull origin branch1:branch2
# The general form seems to be:
git pull <remote> <from_branch>[:to_branch]
以下命令仅在远程分支和本地分支具有相同名称时才有效!(因此它不会回答这个 Stack Overflow 问题)。如果您还没有分支 some_branch 已签出,建议使用此命令!
# Pull FROM a remote branch named `some_branch` TO a local branch named
# `some_branch`, while you do NOT have `some_branch` locally checked-out.
git fetch origin some_branch:some_branch
# General form
git fetch <remote> <from_branch>:<to_branch>
# The above is a special form of `git fetch`, and (I believe) requires that
# `from_branch` and `to_branch` are **the same branch name**. It is roughly
# equivalent to the following *several* commands:
git checkout any_other_branch
# this `git fetch` cmd updates the **locally-stored**, hidden, remote-tracking
# branch named `origin/some_branch` with the latest changes from the branch
# by this name stored on the remote server named `origin`
git fetch origin some_branch
git checkout some_branch
git merge origin/some_branch # merge `origin/some_branch` into `some_branch`
git checkout any_other_branch # go back to the branch we started on
注意事项:
- 与
git push 不同,git pull 没有-u 选项。
- 另请参阅我的另一个答案:How to change the owner of a PR on GitHub / How to commandeer an open GitHub PR
-
git fetch origin some_branch:some_branch 命令使用相同的 some_branch 名称完成两次 -- 在命令的两个位置。区别很简单,git fetch origin some_branch 仅更新名为origin/some_branch 的本地存储、隐藏、远程跟踪分支,该分支的最新更改存储在名为@987654405 的远程服务器上@,而 git fetch origin some_branch:some_branch 这样做 PLUS 也会使用这些更改更新本地存储的可见 some_branch。
- 如果您对此感到困惑,您需要了解每 1 个
some_branch 你认为你实际上有多达 3 个分支:1) 本地分支 some_branch,2) 远程服务器上的远程分支 some_branch,名为 origin,以及 3) 本地存储、隐藏、远程跟踪分支,名为 origin/some_branch。在这里阅读更多信息。我第一次了解到每个分支 3 个分支 的概念:How do I delete a Git branch locally and remotely?。另请参阅该答案下的 my comment here。
3。配置本地分支以跟踪或取消跟踪远程分支
您可以设置本地分支名为branch2跟踪上游分支名为branch1在推送的同时使用上面显示的git push -u cmd。
您还可以设置名为branch2 的本地分支来跟踪名为branch1 的上游分支,如下所示:
# Set branch2 to track origin/branch1 (`branch1` on remote `origin`)
git branch --set-upstream-to=origin/branch1 branch2
# OR (same thing as just above)
git branch -u origin/branch1 branch2
# General form
git branch -u <remote>/<to_branch> [from_branch]
# OR, same as above if the currently-checked-out branch is `branch2`
git branch --set-upstream-to=origin/branch1
# OR (same thing as just above)
git branch -u origin/branch1
# General form
git branch -u <remote>/<to_branch>
要为branch2 取消设置您的上游分支,使其不再跟踪先前设置的上游分支(在上面的示例中为origin/branch1),请运行以下命令:
git branch --unset-upstream branch2
# OR, same as above if the currently-checked-out branch is `branch2`
git branch --unset-upstream
再次,如上所示,要查看您的分支的上游分支当前设置的内容,请运行 double-verbose (-vv) git branch命令:
git branch -vv
参考资料:
- 我第一次学习
git push -u origin local_FROM_branch:remote_TO_branch 语法的地方:@Adam Dymitruk's answer
- https://devconnected.com/how-to-set-upstream-branch-on-git/
- How do I delete a Git branch locally and remotely?
我写过的相关git主题:
- 初学者:
- Create a branch in Git from another branch
- 中级:
- How to cherry-pick multiple commits
- 高级:
- How to get just one file from another branch?
- Who is "us" and who is "them" according to Git?