如何轻松地将本地Git分支推送到一个不同名称的远程分支?

xqk2d5yq  于 2023-02-07  发布在  Git
关注(0)|答案(8)|浏览(306)

我一直在想,是否有一种简单的方法可以将本地分支与具有不同名称的远程分支推拉,而不必总是指定两个名称。
例如:

$ git clone myrepo.git
$ git checkout -b newb
$ ...
$ git commit -m "Some change"
$ git push origin newb:remote_branch_name

现在,如果有人更新了remote_branch_name,我可以:

$ git pull

而且所有内容都被合并/快进。但是,如果我在本地"newb"中进行更改,我无法:

$ git push

相反,我必须:

% git push origin newb:remote_branch_name

看起来有点傻。如果git-pull使用git-config branch.newb.merge来决定从哪里拉取,为什么git-push不能有一个类似的配置选项?有一个很好的捷径吗?或者我应该继续走很长的路?

nfeuvbwi

nfeuvbwi1#

在执行初始推送时,请添加-u参数:

git push -u origin my_branch:remote_branch

随后的推送将到达您想要的位置。
编辑:
根据评论,这只会产生拉力。

git branch --set-upstream

应该可以。

ca1c2owp

ca1c2owp2#

当然可以,只要将push.default设置为upstream,就可以将分支推送到它们的上游(这与pull将从branch.newb.merge拉取的相同,由branch.newb.merge定义),而不是将分支推送到名称匹配的分支(这是push.defaultmatching的默认设置)。

git config push.default upstream

注意,在Git www.example.com之前,这个选项被称为tracking,而不是upstream1.7.4.2,所以如果你使用的是旧版本的Git,请使用trackingpush.default选项是在Git 1.6.4中添加的,所以如果你使用的是旧版本,就根本没有这个选项,需要显式地指定要推送到的分支。

rmbxnbpk

rmbxnbpk3#

Adam的命令现在已弃用。您可以用途:

git branch --set-upstream-to origin/my_remote_branch my_local_branch

my_local_branch的上游分支设置为origin/my_remote_branch

4sup72z8

4sup72z84#

如何轻松地将本地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.推送到另一个分支
1.从另一根树枝上拔出
1.设置和取消设置要跟踪的上游分支
这里有太多不完整和部分的答案,这给我留下了很多问题和很多需要改进的地方。因此,经过大量的努力、研究和实验,我试图提供一个完整的解决方案。

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部分是 * optional *。我的意思是,要从一个名称的本地分支推送到另一个名称的远程分支,该部分不是可选的,但是,作为一个通用的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

您可能当前 checkout 了本地branch3,并且认为git push origin branch2会将您的本地branch3推送到远程branch2,因为您当前在系统上 checkout 了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会从你当前 checkout 的分支推送,那么上面的cmd的缩写形式会产生非常混乱的行为。下面是Nota bene注解,总结了上面描述的行为:

  • 注:在一般形式git push <remote> <from_branch>[:to_branch]中,如果您不使用:to_branch指定远程TO分支,则假定它与remote上的本地FROM分支from_branch同名!这意味着如果您只键入git push origin branch2而不是git push origin some_other_branch:branch2,它会从本地branch2推送到branch2的远程副本,即使您在运行命令时没有在本地 checkout branch2!如果您 * 以为 * 键入git push origin branch2只是告诉您当前 checkout 的分支,这可能会非常令人困惑,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 *(-vvgit branch cmd:

git branch -vv

样本输出:
在这里您可以看到上游分支是origin/master,这意味着远程上名为originmaster分支:

* master b2f0466 [origin/master] c/array_filter_and_remove_element.c: add O(n) in-place solution

注:
1.上面-vv的意思是"双冗余",这意味着它将打印git branch不仅仅是冗余,而是双冗余,或者额外冗余,现在打印的"额外冗余"内容包括方括号中的上游分支,如上图所示:[origin/matser].
1.您可以使用git remote -v查看所有遥控器。origin是上面示例中显示的遥控器。

2.从名称不同的远程分支拉入到本地分支

  • *[如果您已在本地 checkout 分支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]
    • 以下命令仅在 * 远程分支和本地分支具有相同名称时有效! (因此它不会回答此堆栈溢出问题)。如果尚未 checkout 分支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

注:
1.与git push不同,git pull没有-u选项。
1.另见我的另一个回答:如何更改GitHub上PR的所有者/如何征用开放的GitHub PR

  1. git fetch origin some_branch:some_branch命令是使用相同的some_branch名称完成的--在命令中的两个位置使用两次。差别仅在于git fetch origin some_branch仅使用来自存储在名为origin的远程服务器上的具有该名称的分支的最新改变来更新名为origin/some_branch本地存储的、隐藏的远程跟踪分支。而git fetch origin some_branch:some_branch执行该操作,并且也用这些改变来更新本地存储的可见some_branch
    1.如果您对此感到困惑,您需要了解 * 您 * 认为 * 拥有的每1个some_branch *,实际上最多有 * 3个分支 *:1)本地分支some_branch,2)远程分支some_branch,位于名为origin的远程服务器上,以及3)本地存储的、隐藏的、远程跟踪的分支,名为origin/some_branch。阅读此处了解更多信息,以及我第一次了解3个分支这个概念的地方:我如何在本地和远程删除一个Git分支?。也可以在这个答案下面看到我的评论。

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 *(-vvgit branch cmd:

git branch -vv

参考文献:

1.我第一次学习git push -u origin local_FROM_branch:remote_TO_branch语法的地方:@亚当·迪米特鲁克的回答

  1. https://devconnected.com/how-to-set-upstream-branch-on-git/
    1.如何在本地和远程删除Git分支?

我写过的git相关主题:

1.开始:
1.在Git中从另一个分支创建分支
1.中间体:
1.如何选择多个提交
1.高级:
1.如何从另一个分支只获取一个文件?
1.根据Git,谁是"我们",谁是"他们"?

ct3nt3jp

ct3nt3jp5#

如何在Git上推送到不同名称的分支

您通常会将本地分支推送到同名的远程分支,但并非总是如此。
要推送到不同名称的分支,只需指定branch you want to push和要推送到的分支的名称(用冒号(:)分隔)。
例如,如果要将名为some-branch的分支推送到my-feature

(some-branch)$ git push origin some-branch:my-feature
Total 0 (delta 0), reused 0 (delta 0)
To github.com:johnmosesman/burner-repo.git
 + 728f0df...8bf04ea some-branch -> my-feature

如何将所有本地分支推送到远程

你不需要经常从本地推送所有分支,但是如果你这样做的话,你可以添加--all标志:

(main)$ git branch
* main
  my-feature

(main)$ git push --all
...
To github.com:johnmosesman/burner-repo.git
   b7f661f..6e36148  main -> main
 * [new branch]      my-feature -> my-feature
ctehm74n

ctehm74n6#

是的,默认情况下,有一个配置选项可以将git推送到上游分支。
使用以下语句集,这样就不必每次都执行git push origin local:remote

# Set remote branch with a different name as an upstream branch 
# for local branch currently checked out
git branch --set-upstream-to origin/remote_branch_name

# Change the default behavior for git-push (see manpage for git-config)
git config push.default upstream

# Now git will push to the upstream branch by default
git push

将当前分支的上游设置为一个不同名称的远程分支后,需要将git push的默认行为更改为upstream(请参阅git-config的手册页)。现在,git push将遵守这些规则并推送到设置的上游。

vshtjzan

vshtjzan7#

推送并创建临时远程分支

如果您想要:

  • 将当前分支推送到新名称下的remote,但是:
  • 不改变当前分支的远端跟踪分支,并且:
  • 不要在新名称下创建本地分支,

那么就这么简单了:

git push origin HEAD:temp-branch-name
  • 注意:你可以用任何其他分支或提交ID替换HEAD来推送它。*
1tuwyuhd

1tuwyuhd8#

以下是对我有效的过程。

git clone original-repo-url
git remote rename origin upstream
git remote add origin new-repo-url

现在你的新的repo将是'origin',而原来的repo是'upstream'。通过运行git remote-v确认。(边注:Upstream用于从原始存储库中获取数据--以便使本地副本与您要贡献的项目保持同步--Origin用于拉入和推送,因为您可以贡献给自己的存储库)。
git push origin master
现在,新的远程repo的master(在Github上)将与原始master同步,但它不会有任何特性分支。

git rebase upstream/branch-name
git push origin master

重新建立库是一个智能合并,然后再次推到主库,你会看到所选的特性分支在新的库中作为主库。
可选:

git remote rm upstream
git remote add upstream new-repo-url

相关问题