我一直在想是否有一种简单的方法来推拉具有不同名称的本地分支和远程分支,而不总是指定两个名称。

例如:

$ 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.new .merge来决定从哪里拉,为什么git-push不能有一个类似的配置选项?有什么捷径吗,还是我应该继续走这条路?


当前回答

推送并创建一个临时远程分支

如果你想:

以新名称将当前分支推到远程,但是: 不更改当前分支的远程跟踪分支,并且: 不要用新名字创建本地分支,

其实很简单:

git push origin HEAD:temp-branch-name

注意:您可以将HEAD替换为任何其他分支或提交ID。

其他回答

确定。只需将push.default设置为upstream,将分支推到它们的上行流(这与pull将从那里进行拉取相同,由branch.new .merge定义),而不是将分支推到名称匹配的分支(这是push.default的默认设置,matching)。

git config push.default upstream

请注意,在Git 1.7.4.2之前,这被称为跟踪而不是上游,所以如果您使用的是旧版本的Git,请使用跟踪。push.default选项是在Git 1.6.4中添加的,所以如果你使用的是较旧的版本,你根本就没有这个选项,需要显式地指定要推送的分支。

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

您通常会将本地分支推到同名的远程分支,但并非总是如此。

要推到不同名称的分支,只需要指定要推的分支和要推的分支的名称,用冒号(:)分隔。

例如,如果你想把一个叫做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

以下是对我行之有效的方法。

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

现在你的新回购将是“原点”,原始回购是“上游”。运行git remote -v确认。(附注:Upstream用于从原始的回购中获取数据——为了使你的本地副本与你想要贡献的项目保持同步——而origin用于拉和推,因为你可以贡献给自己的回购)。

Git push origin master

现在你的新远程回购主服务器(在Github上)将与原始主服务器同步,但它不会有任何功能分支。

git rebase upstream/branch-name
git push origin master

Rebase是一个聪明的合并。然后再次推到master,你会在新的repo上看到所选的功能分支作为master。

可选:

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

是的,有一个配置选项,默认情况下让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推送到上游的默认行为(参见manpage中的git-config)。 现在,git push将遵循这些规则并推送到上游的集合。

如何使用不同的名称轻松地将本地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. 从本地分支推到具有不同名称的远程分支

要从你的本地分支2推到远程分支1,你必须像这样指定两个分支:

# 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的简短形式会从当前签出的分支中推出,那么它会产生非常令人困惑的行为。以下是对上述行为的总结:

NB: In the general form git push <remote> <from_branch>[:to_branch], if you don't specify the remote TO branch with :to_branch, it is assumed to be the same name as your local FROM branch, from_branch, on the remote! This means if you type only git push origin branch2 instead of git push origin some_other_branch:branch2, it pushes FROM your local branch2 TO the remote copy of branch2, EVEN IF YOU DIDNT HAVE branch2 locally checked-out at the time of running the command! This can be VERY CONFUSING if you thought typing git push origin branch2 had just told your currently-checked out branch, some_other_branch, to push to branch2 on the remote and instead, the local branch2 got pushed to the remote branch2.

通用表单的文档(git push <remote> <from_branch>[:to_branch])很难找到,但实际上可以在顶部的“<refspec>…”部分的man git push页面中找到:

<refspec>参数的格式是一个可选的加号+,后面跟着源对象<src>,后面跟着冒号:,后面跟着目标ref <dst>。

然后是:

:<dst>部分可以省略——这样的推送将更新一个<src>通常更新的ref,而不会在命令行上更新任何<refspec>。

我认为这个文档不是直观的,很难理解,但是,如果没有一些例子和我上面的解释。

你也可以在推送的同时设置上游分支:

# 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]

作为上面命令输出的一部分,你应该看到:

分支'branch2'设置为从'origin'跟踪远程分支'branch1'。

为了让这里发生的事情更明显,要知道上面的两个命令中的任何一个都等价于下面两个单独的命令:

git push origin branch2:branch1
git branch -u origin/branch1

现在,要查看你的分支的上游分支当前设置为什么,运行double-verbose (-vv) git分支cmd:

git branch -vv

样例输出: 在这里你可以看到上游分支是origin/master,这意味着远程命名为origin的主分支:

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

注:

上面的-vv表示“double verbose”。这意味着它将不只是详细地打印git分支,而是双倍详细地打印,或者额外详细地打印。现在打印的“额外详细”内容包括方括号中的上游分支,如上面所示:[origin/matser]。 你可以用git remote -v查看你所有的遥控器。原点是上面例子中显示的遥控器。

2. 从具有不同名称的远程分支提取到本地分支

[如果您已经在本地签出分支branch2,建议使用!]要在名为origin的远程分支上拉FROM 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]

以下命令仅在远程分支和本地分支具有相同的名称时才有效!(因此它没有回答这个堆栈溢出的问题)。如果你还没有签出分支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

注:

Unlike git push, git pull does NOT have a -u option. See also another of my answers: How to change the owner of a PR on GitHub / How to commandeer an open GitHub PR The git fetch origin some_branch:some_branch command is done with the same some_branch name used twice--in both locations in the command. The difference is simply that git fetch origin some_branch only 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, whereas git fetch origin some_branch:some_branch does that PLUS also updates the locally-stored visible some_branch with those changes too. If you feel confused about this, you need to learn that for every 1 some_branch you think you have, you actually have up to 3 branches: 1) a local branch some_branch, 2) a remote branch some_branch on a remote server named origin, and 3) and locally-stored, hidden, remote-tracking branch named origin/some_branch. Read here for more info. and for where I first learned this concept of 3 branches per branch: How do I delete a Git branch locally and remotely?. See also my comment here, under that answer.

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分支cmd:

git branch -vv

引用:

我第一次学习git push -u origin local_FROM_branch:remote_TO_branch语法:@Adam Dymitruk的答案 https://devconnected.com/how-to-set-upstream-branch-on-git/ 如何在本地和远程删除Git分支?

我写过的相关git主题:

初学者: 在Git中从另一个分支创建一个分支 中级: 如何挑选多个提交 高级: 如何从另一个分支获得一个文件? 根据Git,谁是“我们”,谁是“他们”?