我在 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
,这不是很明显吗?我怎样才能使它成为默认行为?
branch.autosetupmerge
的默认值意味着新分支的上游配置仅在从远程跟踪分支(例如 <remote-name>/<branch-name>
)创建分支时自动设置(参见 git-config(1))。您可能正在从现有的本地分支创建分支。如果您有效地直接从远程分支的尖端分支(尽管位于本地分支上),那么您可以使用 git branch my_branch <remote-name>/<branch-name>
自动设置上游配置。
--set-upstream
选项已弃用。您应该改用 --track
或 --set-upstream-to
。
--set-upstream
,那么 git 开发人员可能应该将它从当您运行 git push
时显示的帮助消息中删除,而没有选项并且没有设置上游?
git branch --set-upstream
已弃用。 git push --set-upstream
不是。
不依赖于记住 git branch --set-upstream
1 语法的快捷方式是:
git push -u origin my_branch
...你第一次推送那个分支。或者,从同名分支推送到当前分支(对于别名很方便):
git push -u origin HEAD
您只需使用 -u
一次,就可以像 git branch --set-upstream
一样在您的分支和 origin
处的分支之间建立关联。
就个人而言,我认为必须在您的分支和远程分支之间明确建立关联是一件好事。规则是 different for git push
and git 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
此更改及其原因在 the release notes for git 1.8.0, release candidate 1 中进行了描述:
说 git branch --set-upstream origin/master 很诱人,但这告诉 Git 安排本地分支 origin/master 与当前签出的分支集成,这不太可能是用户的意思。该选项已弃用;改用新的 --set-upstream-to(带有简短的 -u)选项。
你可以用更少的打字来实现这一点。首先,改变你的推送方式:
git config --global push.default current
这将推断出 origin my_branch
部分,因此您可以执行以下操作:
git push -u
这将创建具有相同名称的远程分支并跟踪它。
git push -u
时,git 如何推断 origin
?是否假设存储库已被克隆,因此当前分支的远程设置为 origin
?
pull
时,您必须指定从哪里开始。 -u
设置源站和本地存储库之间的分支跟踪。
push
运行不同的命令——这违背了这个问题的全部观点。简而言之,没有好的答案。 Git 开发人员在面对广泛的社区异议时坚持保留这种尴尬的用户体验 (AUX) 是……启发性的。并且令人沮丧。 (主要是令人沮丧的。)
这是我最常使用的 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.
...
此外,在终端中输入脏话也很有趣。
你可以简单地
git checkout -b my-branch origin/whatever
首先。如果您将 branch.autosetupmerge
或 branch.autosetuprebase
(我的最爱)设置为 always
(默认为 true
),my-branch
将自动跟踪 origin/whatever
。
请参阅git help config
。
git checkout -t origin/whatever
,它也选择 whatever
作为新的分支名称。很方便!
-u
/--set-upstream
。
git checkout -t origin/whatever
对我不起作用:fatal: Cannot update paths and switch to branch 'whatever' at the same time.
git checkout -b my-branch origin/whatever
也有同样的错误(我正在尝试创建一个本地或远程不存在的新分支):fatal: Cannot update paths and switch to branch 'whatever' at the same time.
您可以通过两种方式更简单地设置上游。首先在创建分支时:
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
git branch -u origin/my-branch
后,我可以运行 git pull
来下拉我的更改。
-b my-branch
的情况下执行 git checkout -t origin/my-branch
,它只会自动推断 my-branch
以获取本地分支名称。但是,正如@Spongman 提到的,如果 origin/my-branch
首先不存在,则此命令不起作用。
fatal: 'origin/my-branch' does not appear to be a git repository
对我来说 git push -u origin/my-branch
失败。这有效:git push -u origin my-branch
您可以使用:
git config --global branch.autosetupmerge always
每次创建或签出新分支时,它将链接上游分支。
请参阅https://felipec.wordpress.com/2013/09/01/advanced-git-concepts-the-upstream-tracking-branch/
这也适用于 branch.autosetuprebase
,如果您遵循更注重变基的工作流程,但除非您知道自己在做什么,否则不要使用它,因为它会将您的拉取行为默认为变基,这可能会导致奇怪的结果。
--set-upstream
消息
master
。 2. 运行 git checkout -b new_branch
。 3. 向该分支添加提交。 4. git push origin new_branch
。 这会将提交推送到源上的 master
分支(而不是源上名为 new_branch
的新分支)。
顺便说一下,将当前分支推送到同名远程的快捷方式:
$ git push -u origin HEAD
如果以下不起作用:
git config --global push.default current
您还应该更新项目的本地配置,因为您的项目可能具有本地 git 配置:
git config --local push.default current
git fetch --prune
的习惯是值得的,因此如果远程分支被远程删除,您也会在本地删除远程分支。
我个人在 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"
git pushup
,它总是将当前分支推送到原点。我总是可以只使用 git pushup
而不是 git push
👍
git config --global alias.pushup "!git push --set-upstream origin $(git symbolic-ref --short HEAD)"
git config --global push.autoSetupRemote true
OP问:
我了解到我可以使用它: git branch --set-upstream my_branch origin/my_branch 但是为什么我需要为我创建的每个分支都这样做呢?
您不需要一直设置上游。不再是(十一年后)。
在 Git 2.37(2022 年第三季度)中,git config --global push.autoSetupRemote true
将为您解决这些问题。
请参阅 Tao Klerks (TaoK
) 的 commit 05d5775、commit 8a649be、commit bdaf1df(2022 年 4 月 29 日)。
(由 Junio C Hamano -- gitster
-- 在 commit f49c478 中合并,2022 年 5 月 26 日)
push:新配置选项“push.autoSetupRemote”支持“简单”推送签名者:Tao Klerks
在一些“简单”的集中式工作流程中,用户希望远程跟踪分支名称与本地分支名称匹配。 “git push”(man)推送到分支的远程版本/实例,“git pull”(man)将任何更改拉到远程分支(同一用户在另一个地方或其他用户所做的更改)。 push.default 默认选项“simple”支持这种期望,它拒绝默认推送不匹配的跟踪分支名称,以及新的 branch.autosetupmerge 选项“simple”,它只为同名远程设置远程跟踪分支机构。当用户创建了新分支但尚未推送(并且 push.default 未设置为“当前”)时,会提示用户“当前分支 %s 没有上游分支”错误,并且有关如何推送和添加跟踪的说明。这个错误有助于每个分支遵循一次建议永远“解决”该分支的问题,但对于“简单”集中式工作流程来说不方便,这始终是正确的做法,所以最好只做。使用新的配置设置 push.autoSetupRemote 支持此工作流程,这将导致默认推送,当没有配置远程跟踪分支时,推送到远程和 --set-upstream 上的同名。当遇到“当前分支 %s 没有上游分支”错误时,还添加一个提供此新选项的提示,并添加相应的测试。
新的提示是:
要让没有跟踪上游的分支自动发生这种情况,请参阅“git help config”中的“push.autoSetupRemote”
git config
现在在其 man page 中包含:
push.autoSetupRemote 如果设置为“true”,当当前分支不存在上游跟踪时,默认推送时假定 --set-upstream;此选项与 push.default 选项“simple”、“upstream”和“current”一起生效。如果默认情况下您希望将新分支推送到默认远程(如 'push.default=current' 的行为)并且您还希望设置上游跟踪,这很有用。最有可能从此选项中受益的工作流程是“简单”的中央工作流程,其中所有分支都应在远程具有相同的名称。
对于它的价值,如果您尝试跟踪远程上已经存在的分支(例如 origin/somebranch)但尚未在本地检查它,您可以执行以下操作:
$ git checkout --track origin/somebranch
注意:“-t”是“--track”选项的缩短版本。
这立即建立了相同的关联。
git checkout somebranch
是等价的。
git fetch
后才有效吗?
git fetch
或 git pull
时都会发生这种情况。不过,我从来没有发现这是一个问题。
更新: push.autoSetupRemote
现在终于以更简单的方式解决了这个问题!有关详细信息,请参阅 other answer on that here。
原答案:
我每次都使用这个 Git 别名,而不是从 Git 复制/粘贴建议:https://gist.github.com/ekilah/88a880c84a50b73bd306
下面复制的源(将其添加到您的 ~/.gitconfig
文件中):
[alias]
pushup = "!gitbranchname() { git symbolic-ref --short HEAD; }; gitpushupstream() { git push --set-upstream origin `gitbranchname`; }; gitpushupstream"
您还可以明确告诉 git pull 要拉哪个远程分支(如错误消息中所述):
git pull <remote-name> <remote-branch>
但是请注意这一点:如果您在不同的分支上并进行显式拉取,则您拉取的 refspec 将被合并到您所在的分支中!
git branch --set-upstream-to=origin/master<branch_name>
您可以设置一个非常好的别名来处理此问题,而无需过于冗长的语法。
我在 ~/.gitconfig
中有以下别名:
po = "!git push -u origin \"$(git rev-parse --abbrev-ref HEAD)\""
在新分支上提交后,您只需键入以下命令即可推送新分支:
git po
po
? push origin
?如果多次运行会发生什么?
git push -f
别名设置为 git pf
,所以一旦源已经被推送,我就会使用它。
HEAD
我做了一些与许多其他用户类似的事情,但我想分享它作为替代方案,因为我没有看到其他人发布这个。
alias gpu='git push --set-upstream origin $(git branch --show-current)'
(oh-my-zsh 已经有一个 gpu 别名,所以在 .oh-my-zsh/plugins/git/git.plugin.zsh 中进行了编辑)
对于那些寻找与 git pull
一起使用的别名的人,这就是我使用的:
alias up="git branch | awk '/^\\* / { print \$2 }' | xargs -I {} git branch --set-upstream-to=origin/{} {}"
现在每当你得到:
$ git pull
There is no tracking information for the current branch.
...
赶紧跑:
$ up
Branch my_branch set up to track remote branch my_branch from origin.
$ git pull
你可以走了
99% 的时间我想将上游设置为同名的分支,所以我使用它(在 *nix 或 Git Bash 中):
git branch --set-upstream-to=origin/$(git branch --show-current)
这很好,因为它与分支无关。请注意,子命令 git branch --show-current
会打印您当前的分支名称,如果您已分离,则不会打印任何内容。
旁注:我已经设置了可以使用 git push -u
的配置,因此我很少需要这样做。但有时我仍然会这样做,通常是当我决定要将本地更改重置为遥控器上的任何内容时,那时我意识到我之前在没有 -u 的情况下进行了推送。因此,通常在设置上游后我要运行的下一个命令是重置到远程分支:
git reset --hard @{u}
这也恰好与分支无关。 (也许我真的不喜欢输入我的分支名称。)
在 git 2.37.0
或更高版本中,您可以告诉 git 自动设置远程。这是用
git config --global --add --bool push.autoSetupRemote true
然后你可以只写 git push
它将推送到默认遥控器。
因为 git 具有将不同分支推送/拉到不同“上游”存储库的酷炫能力。您甚至可以在同一个分支上使用单独的存储库进行推送和拉取。这可以创建一个分布式的多级流程,我可以看到这在 Linux 内核等项目中很有用。 Git 最初是为该项目而构建的。
因此,它不会假设您的分支应该跟踪哪个 repo。
另一方面,大多数人不以这种方式使用 git,因此它可能为默认选项提供了一个很好的案例。
Git 通常是相当低级的,它可能会令人沮丧。但是有 GUI,如果您仍想从 shell 中使用它,编写帮助脚本应该很容易。
你也可以做git push -u origin $(current_branch)
我们使用 phabricator,不使用 git 推送。我必须创建适用于 Linux/mac 的 bash 别名
vim ~/.bash_aliases
new_branch() {
git checkout -b "$1"
git branch --set-upstream-to=origin/master "$1"
}
节省
source ~/.bash_aliases
new_branch test #instead of git checkout -b test
git pull
这是 git push 的 bash 别名,每次推送都可以安全运行,并且会在为第一次推送设置上游和之后进行正常推送之间自动切换。
alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'
我只想做这样的事情:
git checkout -b my-branch
git commit -a -m "my commit"
git push
由于我没有找到更好的解决方案,我刚刚在 ~/.bashrc
上创建了一个 bash 别名:
alias push="git push -u origin HEAD"
现在只需执行 push
命令即可完成工作(您也可以在 ~/.gitconfig
上添加此别名并使用其他名称,例如 pushup
)
由于这个问题(仅限 OS X),我重新发现了 legit
。现在我在分支时使用的是这两个命令:
legit publish [<branch>]
将指定的分支发布到远程。 (别名:pub
)
legit unpublish <branch>
从远程移除指定的分支。 (别名:unp
)
SublimeGit 默认支持 legit
,这使得整个分支例程就像按 Ctrl-b 一样简单。
这里有很多很好的答案,但是,它们都要求您在运行 git pull
之前正确执行其他操作
通过创建本地正确跟踪的远程分支,让别名可以执行诸如“使 git push 以应有的方式工作”之类的操作肯定会有所帮助。但是,当您忘记使用它们或经历不同的工作流程时,这些都对您没有帮助。
这是一个 bash 函数,您可以通过检测何时没有配置远程合并目标,但远程上有一个与您的本地分支同名的分支,可以使用它按照它应该工作的方式进行拉取,并将该分支设置为合并目标,然后拉。
git-pulldown() {
head="$(git rev-parse --abbrev-ref HEAD)"
if [[ $(git config "branch.$head.merge") ]]; then #there's already a merge target configured, just pull as normal from there
git pull
else
if [[ $(git ls-remote --heads origin $head) ]]; then #there is an upstream branch existing with the same name as our branch
git branch --set-upstream-to origin/$head #set merge target to upstream branch with same name
git pull
else #fail with explanation
echo "Branch $head has no upstream or merge target! You will likely have to push first, or manually configure it"
return 1
fi
fi
}
显然没有支持的方式来覆盖 git 命令的默认选项。根据 this answer 到 Define git alias with the same name to shadow original command,我们可以覆盖 bash 中 git push
的行为以始终调用 git push -u
。将以下内容放入您的 ~/.bash_profile
文件中,它应该等效于每次推送时运行 --set-upstream 。
function do_git {
cmd=$1
shift
myArgs=( "$@" )
if [ "$cmd" == "push" ]; then
myArgs=( "-u" "${myArgs[@]}" )
fi
myArgs=( "$cmd" "${myArgs[@]}" )
$(which git) "${myArgs[@]}"
}
alias git='do_git'
-u
,您也可以使用该标志再次运行推送,它将开始跟踪。git push -u origin master
的更完整解释:stackoverflow.com/a/17096880/6309alias gpo="git push --set-upstream origin $(git branch | awk '/^\* / { print $2 }')"