如何避免执行“git branch --setup-upstream”命令,而是默认自动设置远程跟踪?

1960
我在Git中创建了一个新的分支。
git branch my_branch

推一下:
git push origin my_branch

现在假设有人在服务器上做了一些更改,我想要从origin/my_branch拉取代码。我执行以下操作:
git pull

但是我得到:
You asked me to pull without telling me which branch you
want to merge with, and 'branch.my_branch.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
use something like the following in your configuration file:

    [branch "my_branch"]
    remote = <nickname>
    merge = <remote-ref>

    [remote "<nickname>"]
    url = <url>
    fetch = <refspec>

See git-config(1) for details.

我了解到我可以让它运作起来的方法是:
git branch --set-upstream my_branch origin/my_branch

为什么我每次创建分支都需要这样做呢?难道不明显吗,如果我将my_branch推送到origin/my_branch,那么我肯定想将origin/my_branch拉取到my_branch中。我怎样才能将此设置为默认行为呢?

34
branch.autosetupmerge 的默认设置意味着,当从远程跟踪分支(例如 <remote-name>/<branch-name>) 创建分支时,新分支的上游配置才会自动设置 (参见 git-config(1)). 你可能是从现有的本地分支创建分支。如果你要直接从远程分支的最新提交(尽管你在本地分支上)创建分支,则可以使用 git branch my_branch <remote-name>/<branch-name> 自动设置上游配置。 - Chris Johnsen
27
FYI,--set-upstream选项已被弃用。应使用--track--set-upstream-to代替。 - Sean the Bean
215
如果--set-upstream已经被弃用,那么Git开发者应该从帮助信息中移除它,这样当你在没有设置上游分支的情况下运行git push时,就不会再显示该选项了。 - Christopher Hunter
24
自从你发表评论以来已经过了一年,但是它仍然没有改变。这只是一个草率的反馈意见,还是可能有一个我们不知道的技术上明智的原因让它保留下来? - Konrad Viltersten
50
git branch --set-upstream 已经被废弃,git push --set-upstream 没有被废弃。 - Rag
显示剩余7条评论
29个回答

1953

Git v2.37.1 及以上版本

如果您正在使用此版本或更高版本,则可以使用此新的配置项自动设置远程跟踪:

git config --global push.autoSetupRemote true

之后,当您执行 git push 时,跟踪将自动设置。无需使用 git push -u origin my_branch


一个不需要记忆 git branch --set-upstream 语法的快捷方式1是执行以下命令:

git push -u origin my_branch

...第一次推送该分支时。或者,从同名分支(对于别名很方便)推送到当前分支:

git push -u origin HEAD

你只需要使用-u一次,这将建立你的分支与origin上的分支之间的关联,就像git branch --set-upstream一样。
个人认为明确地建立本地分支和远程分支之间的关联是一件好事。可惜的是,对于git pushgit pull而言规则是不同的

1这可能听起来很傻,但我经常忘记指定当前分支,认为那是默认值 - 实际上不是,结果非常令人困惑。

更新于2012年10月11日:显然我不是唯一一个发现很容易出错的人!感谢VonC指出git 1.8.0引入了更明显的git branch --set-upstream-to,如果你在分支my_branch上,可以使用以下命令:

git branch --set-upstream-to origin/my_branch

...或者使用短选项:

git branch -u origin/my_branch

这个更改及其原因在git 1.8.0版本,发布候选版1的发行说明中描述:

使用git branch --set-upstream origin/master是很诱人的,但这告诉Git安排本地分支origin/master与当前检出的分支集成,这极不可能是用户想要的。该选项已被弃用;请改用新的--set-upstream-to(简短而甜美的-u)选项。


114
请注意,即使您第一次推送时忘记了使用“-u”选项,只要再次使用该选项重新推送,就可以开始跟踪了。 - Henrik N
89
这些都不能满足使用无参数的git push命令的需求。因此,当我第一次将新分支移动到远程时,我仍然需要记住输入'git push -u origin my-branch'。 - Karl the Pagan
9
备忘录:第一次使用“git push -u origin master”的更完整解释:https://dev59.com/X2Qn5IYBdhLWcg3wGT8X#17096880 - VonC
30
我也讨厌记住那种语法,所以我创建了以下别名:alias gpo="git push --set-upstream origin $(git branch | awk '/^\* / { print $2 }')"。该别名可以使Git推送当前分支到远程仓库并关联起来,无需手动输入分支名称。 - lillialexis
146
没问题,但我仍认为原帖作者的抱怨是合理的。你创建一个本地分支,在其上工作,然后将其推送到 origin 分享(不带参数);为什么不应该设置 upstream 呢?有没有一些理由让在推送新分支到远程时不设置 upstream 呢? - GaryO
显示剩余17条评论

1795

您可以用更少的输入来实现这一点。首先,改变您的推送方式:

git config --global push.default current

这将推断出origin my_branch部分,因此您可以执行:

git push -u

这将同时创建与相同名称的远程分支并将其跟踪。


7
为什么在新创建的存储库中创建新分支并运行git push -u时,Git 可以推断出 origin?这是因为假设该存储库已被克隆,因此当前分支已将其远程设置为 origin 吗? - Piotr Dobrogost
125
如果 git 默认值更好的话,它可以使许多事情更易于使用。这应该是默认设置。 - phreakhead
20
请注意,“current”比使用“simple”做同样的事情稍微不太安全,参见https://dev59.com/xGAg5IYBdhLWcg3wLIPS。 - Air
37
可以的,但是当你试图 pull 时,你需要指定从哪里进行。-u 设置了 origin 和本地仓库之间的分支跟踪关系。 - Zamith
41
尽管稍微方便了一些,但这仍然要求运行一个不同的命令来执行第一个和唯一的 push,这违背了这个问题的全部意义。简而言之,没有好答案。Git开发人员坚持在广泛的社区反对声中保留这种尴尬的用户体验(AUX),这是......启发性的。也是令人沮丧的。(主要是沮丧的。) - Cecil Curry
显示剩余12条评论

215

这是我最常使用The Fuck的方式。

$ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin master

$ fuck
git push --set-upstream origin master [enter/↑/↓/ctrl+c]
Counting objects: 9, done.
...

此外,在终端中输入脏话是很有趣的。


6
有趣的事实:只有2.4%的程序员不同意上述陈述。 - mirekphd
1
如果您正在进行对编程的配对编程,您可能想设置不同的别名 :-D。为此,您可以在您的 .bashrc 或者 .zshrc 配置文件中设置别名,像这样:eval $(thefuck --alias fix)我已经将别名设置为“fix”,而不是默认值“fuck”。参考 - https://github.com/nvbn/thefuck#manual-installation - Kishan B

115
git config --global push.autoSetupRemote true

请问:

I learned that I can make it work with:

git branch --set-upstream my_branch origin/my_branch

But why do I need to do this for every branch I create?

您不需要一直设置上游。
现在(十一年后)也不需要了。
使用 Git 2.37(2022 年第三季度),git config --global push.autoSetupRemote true 将为您处理这个问题。
请参见 提交 05d5775提交 8a649be提交 bdaf1df(由 Tao Klerks (TaoK) 于 2022 年 4 月 29 日提交)。
(由 Junio C Hamano -- gitster -- 合并于 提交 f49c478,2022 年 5 月 26 日)

push:新的配置选项“push.autoSetupRemote”支持“simple”推送

签名作者:Tao Klerks

在一些“简单”的集中式工作流中,用户希望远程跟踪分支名称与本地分支名称匹配。"git push"(手册) 推送到分支的远程版本/实例,而 "git pull"(手册) 拉取任何对远程分支所做的更改(由同一用户在其他位置或其他用户所做的更改)。
这种期望得到了 push.default 默认选项 "simple" 的支持,该选项拒绝不匹配跟踪分支名称的默认推送,并通过新的 branch.autosetupmerge 选项 "simple" 仅为同名远程分支设置远程跟踪。
当用户创建了一个尚未推送的新分支(并且 push.default 没有设置为 "current")时,用户会收到 "The current branch %s has no upstream branch" 错误提示,并获得有关如何推送和添加跟踪的说明。
这个错误提示很有帮助,因为每个分支只需要按照建议操作一次即可永久“解决”问题,但不方便的是,在“简单”的集中式工作流中,这总是正确的事情,所以最好直接这样做。
使用新的配置设置 push.autoSetupRemote 支持此工作流程,当没有配置远程跟踪分支时,将导致默认推送到远程同名分支并使用 --set-upstream
同时,当遇到 "The current branch %s has no upstream branch" 错误时,还要添加一个提示,提供这个新选项,并添加相应的测试。
新提示为:

要自动为没有跟踪上游的分支执行此操作,请参阅“git help config”中的“push.autoSetupRemote

git config 现在包括在其 手册页面 中:

push.autoSetupRemote

如果设置为 "true",则默认情况下在没有当前分支的上游跟踪时假定使用 --set-upstream 进行推送;

此选项对 push.default 选项 'simple', 'upstream', 和 'current' 生效。

如果您希望新分支默认推送到默认远程(类似于 'push.default=current' 的行为),并且还希望设置上游跟踪,则此选项非常有用。
最有可能从此选项中受益的工作流是 'simple' 中央工作流,其中预计所有分支在远程上具有相同的名称。


8
这个答案应该被接受:执行 git config --global push.autoSetupRemote always 将让你自动跟踪 origin 分支,只要你推送一个分支/提交。 - bneil
在 Mac 上使用 git v2.39.2 时,这并不起作用。它仍然会给出“当前分支没有跟踪信息”的错误提示。 - thomasruns
@thomasruns 奇怪,你是否设置了 push.default 配置? - VonC

105

你可以简单地

git checkout -b my-branch origin/whatever

首先,如果您设置了branch.autosetupmergebranch.autosetuprebase(我最喜欢的)为always(默认为true),my-branch将自动跟踪origin/whatever

请参阅git help config


6
这会产生“致命错误:无法同时更新路径并切换到'my-branch'分支。” - Karl the Pagan
14
顺便说一下,我通常只使用git checkout -t origin/whatever命令,这样也会将whatever作为新分支的名称。非常方便! - cdunn2001
2
@cdunn 这个是理想的,但几乎不一致。该标志应该被称为-u / --set-upstream - Tobu
2
git checkout -t origin/whatever doesn't work for me when trying to create a new branch: fatal: Cannot update paths and switch to branch 'whatever' at the same time. - wisbucky
2
branch.autosetupmerge = false也不起作用。它将上游跟踪设置为本地的“whatever”分支,而不是远程的“origin/whatever”分支。 - wisbucky
显示剩余2条评论

92
你可以用两种简单的方式设置上游。第一种是在创建分支时:
git branch -u origin/my-branch

或者,在创建了一个分支之后,您可以使用这个命令。
git push -u origin my-branch

你可以使用一个命令来同时进行分支、检出和设置上游操作:
git checkout -b my-branch -t origin/my-branch

我个人的偏好是使用两步命令来完成这个操作:

git checkout -b my-branch
git push -u origin my-branch

1
很棒的答案!涵盖了常见的用例。在运行 git branch -u origin/my-branch 后,我可以运行 git pull 来拉取我的更改。 - Benjamin Atkin
6
如果 'origin/my-branch' 不存在,那么 "git checkout -b my-branch -t origin/my-branch" 命令将无法执行。 - Spongman
1
实际上,您只需执行 git checkout -t origin/my-branch 而不需要 -b my-branch,它会自动推断出本地分支名称为 my-branch。但是,正如 @Spongman 提到的那样,如果 origin/my-branch 不存在,则此命令将无法工作。 - wisbucky
1
没问题,@wisbucky,-t 参数可以正常工作。 不过就我个人而言,即使是在我回复这条信息两年后,我仍然更喜欢使用 checkout -b 和 push -u 分成两行来写。这样更加明确,在实验时没有远程分支时也不会出现 checkout -b 的错误,这种情况经常发生 :) - Tzen
2
git push -u origin/my-branch fails for me with fatal: 'origin/my-branch' does not appear to be a git repository. This works: git push -u origin my-branch - stason
在MacOS上使用git v.2.34.1时,单行选项会出现以下错误: git status 分支main 您的分支已经是'origin/main'最新版本。没有要提交的内容,工作树干净 git checkout -b my-branch -t origin/my-branch 致命错误:'origin/my-branch'不是提交,无法从中创建分支'my-branch'。 - Fuczak

66

您可以使用:

git config --global branch.autosetupmerge always

每次创建或检出新分支时,它将链接到上游分支。

参见https://felipec.wordpress.com/2013/09/01/advanced-git-concepts-the-upstream-tracking-branch/

如果您遵循更多关注rebase的工作流程,则使用branch.autosetuprebase也可以,但除非您知道自己在做什么,否则不要使用此功能,因为它会将默认的拉取行为设置为rebase,可能会导致奇怪的结果。


18
无效,我仍然收到“--set-upstream”信息。 - Dorian
4
@Dorian,在你创建分支之前,你需要设置这个。请参考https://dev59.com/dm025IYBdhLWcg3wT0Hq#9753268。 - cdunn2001
我收到了一个致命错误:您当前分支的上游分支与您当前分支的名称不匹配... - Riscie
9
但这并不会将跟踪分支设置为具有相同分支的远程分支,而是设置为当前本地分支。因此,当您进行推送时,它将尝试推送到您在创建新分支之前所在的本地分支。 - Arnold Roa
23
注意这个设置!!在设置后,您将获得以下行为:1. 切换到 master 分支。2. 运行 git checkout -b new_branch 命令。3. 向该分支添加一个提交。4. 运行 git push origin new_branch 命令。此操作会将该提交推送到远程仓库上的 master 分支(而不是推送到名为 new_branch 的新分支)。 - stwr667

43

顺便提一下,将当前分支推送到同名远程分支的快捷方式:

$ git push -u origin HEAD

36

我个人在bash中使用以下别名:

在 ~/.gitconfig 文件中

[alias]
    pushup = "!git push --set-upstream origin $(git symbolic-ref --short HEAD)"

并且在 ~/.bashrc 或者 ~/.zshrc 文件中

alias gpo="git pushup"
alias gpof="gpo -f"
alias gf="git fetch"
alias gp="git pull"

2
我只需要更改.gitconfig文件,然后就可以使用命令“git pushup”,该命令始终将当前分支推送到源。我可以随时使用“git pushup”而不是“git push”。 - thespacecamel
1
只是在这个答案上进行扩展,以设置全局 git 别名(自定义命令)- git config --global alias.pushup "!git push --set-upstream origin $(git symbolic-ref --short HEAD)" - Naren

35
如果下面的方法不起作用:
git config --global push.default current

您还应更新项目的本地配置,因为您的项目可能具有局部 git 配置:

git config --local push.default current

2
更多的解释会很好。第一行代码是做什么的? - papillon
6
这个答案感觉合理。那些提出别名的都是愚蠢的解决方法。而那些为记忆冗长命令序列辩护的人则太迂腐了。 - MarkHu
2
这适用于推送但不适用于拉取。当您推送时,它使用正确的上游,但不设置上游,因此您仍然需要运行一个命令来设置上游,然后才能第一次拉取分支。 - rspeer
@rspeer 不确定你的意思?这适用于拉取,但如果您还没有执行过获取操作(或者拉取也执行了获取操作),则无法检出自上次获取以来在远程创建的分支 - 这一直是这样的。您可以争辩说值得养成运行 git fetch --prune 的习惯,这样如果远程删除了本地删除的远程分支,您也会得到通知。 - Johny Skovdal
@JohnySkovdal 我的意思是:如果你运行这个配置,创建一个分支,并推送该分支,那么你不能拉取更新到你创建的同一分支,因为你没有设置它的上游。许多工作流程可以从自动设置上游中受益,这也是问题所在。 - rspeer
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接