I create a new branch in Git:
git branch my_branch
Push it:
git push origin my_branch
Now say someone made some changes on the server and I want to pull from origin/my_branch
. I do:
git pull
But I 开发者_JAVA百科get:
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.
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? Isn't it obvious that if I push my_branch
into origin/my_branch
, then I would want to pull origin/my_branch
into my_branch
? How can I make this the default behavior?
Git v2.37.1 and above
If you are using the mentioned version or above you can use this new config entry to automatically setup remote tracking:
git config --global push.autoSetupRemote true
After that, when you do git push
tracking is setup automatically. No need for git push -u origin my_branch
A shortcut, which doesn't depend on remembering the syntax for git branch --set-upstream
1 is to do:
git push -u origin my_branch
... the first time that you push that branch. Or, to push to the current branch from a branch of the same name (handy for an alias):
git push -u origin HEAD
You only need to use -u
once, and that sets up the association between your branch and the one at origin
in the same way as git branch --set-upstream
does.
Personally, I think it's a good thing to have to set up that association between your branch and one on the remote explicitly. It's just a shame that the rules are different for git push
and git pull
.
1 It may sound silly, but I very frequently forget to specify the current branch, assuming that's the default - it's not, and the results are most confusing.
Update 2012-10-11: Apparently I'm not the only person who found it easy to get wrong! Thanks to VonC for pointing out that git 1.8.0 introduces the more obvious git branch --set-upstream-to
, which can be used as follows, if you're on the branch my_branch
:
git branch --set-upstream-to origin/my_branch
... or with the short option:
git branch -u origin/my_branch
This change, and its reasoning, is described in the release notes for git 1.8.0, release candidate 1:
It was tempting to say
git branch --set-upstream origin/master
, but that tells Git to arrange the local branchorigin/master
to integrate with the currently checked out branch, which is highly unlikely to be what the user meant. The option is deprecated; use the new--set-upstream-to
(with a short-and-sweet-u
) option instead.
You can make this happen with less typing. First, change the way your push works:
git config --global push.default current
This will infer the origin my_branch
part, thus you can do:
git push -u
Which will both create the remote branch with the same name and track it.
This is my most common use for 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.
...
Also, it's fun to type swear words in your terminal.
You can simply
git checkout -b my-branch origin/whatever
in the first place. If you set branch.autosetupmerge
or branch.autosetuprebase
(my favorite) to always
(default is true
), my-branch
will automatically track origin/whatever
.
See git help config
.
git config --global push.autoSetupRemote true
The OP asks:
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?
You do not need to set upstream all the time.
Not anymore (eleven years later).
With Git 2.37 (Q3 2022), a git config --global push.autoSetupRemote true
will take care of that for you.
See commit 05d5775, commit 8a649be, commit bdaf1df (29 Apr 2022) by Tao Klerks (TaoK
).
(Merged by Junio C Hamano -- gitster
-- in commit f49c478, 26 May 2022)
push
: new config option "push.autoSetupRemote
" supports "simple
" pushSigned-off-by: Tao Klerks
In some "
simple
" centralized workflows, users expect remote tracking branch names to match local branch names.
"git push
"(man) pushes to the remote version/instance of the branch, and "git pull
"(man) pulls any changes to the remote branch (changes made by the same user in another place, or by other users).This expectation is supported by the
push.default
default option "simple
" which refuses a default push for a mismatching tracking branch name, and by the newbranch.autosetupmerge
option, "simple
", which only sets up remote tracking for same-name remote branches.When a new branch has been created by the user and has not yet been pushed (and
push.default
is not set to "current
"), the user is prompted with a "The current branch %s has no upstream branch
" error, and instructions on how to push and add tracking.This error is helpful in that following the advice once per branch "resolves" the issue for that branch forever, but inconvenient in that for the "simple" centralized workflow, this is always the right thing to do, so it would be better to just do it.
Support this workflow with a new config setting,
push.autoSetupRemote
, which will cause a default push, when there is no remote tracking branch configured, to push to the same-name on the remote and--set-upstream
.Also add a hint offering this new option when the "
The current branch %s has no upstream branch
" error is encountered, and add corresponding tests.
The new hint is:
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote
' in 'git help config'
git config
now includes in its man page:
push.autoSetupRemote
If set to "
true
" assume--set-upstream
on default push when no upstream tracking exists for the current branch;This option takes effect with
push.default
options 'simple
', 'upstream
', and 'current
'.It is useful if by default you want new branches to be pushed to the default remote (like the behavior of '
push.default=current
') and you also want the upstream tracking to be set.
Workflows most likely to benefit from this option are 'simple
' central workflows where all branches are expected to have the same name on the remote.
You can set upstream simpler in two ways. First when you create the branch:
git branch -u origin/my-branch
or after you have created a branch, you can use this command.
git push -u origin my-branch
You can also branch, check out and set upstream in a single command:
git checkout -b my-branch -t origin/my-branch
My personally preference is to do this in a two-step command:
git checkout -b my-branch
git push -u origin my-branch
You can use:
git config --global branch.autosetupmerge always
which will link the upstream branch each time you create or checkout a new branch.
See https://felipec.wordpress.com/2013/09/01/advanced-git-concepts-the-upstream-tracking-branch/
This also works with branch.autosetuprebase
, if you follow a more rebase focused workflow, but don't use this unless you know what you're doing, as it will default your pull behavior to rebase, which can cause odd results.
By the way, the shortcut to pushing the current branch to a remote with the same name:
$ git push -u origin HEAD
If the below doesn't work:
git config --global push.default current
You should also update your project's local config, as its possible your project has local git configurations:
git config --local push.default current
I personally use these following alias in bash
in ~/.gitconfig file
[alias]
pushup = "!git push --set-upstream origin $(git symbolic-ref --short HEAD)"
and in ~/.bashrc or ~/.zshrc file
alias gpo="git pushup"
alias gpof="gpo -f"
alias gf="git fetch"
alias gp="git pull"
For what it is worth, if you are trying to track a branch that already exists on the remote (eg. origin/somebranch) but haven't checked it out locally yet, you can do:
$ git checkout --track origin/somebranch
Note: '-t' is the shortened version of '--track' option.
This sets up the same association right off the bat.
Update: push.autoSetupRemote
now solves this in an easier way, finally! See the other answer on that here for more information.
Original answer:
I use this Git alias instead of copy/pasting the suggestion from Git every time: https://gist.github.com/ekilah/88a880c84a50b73bd306
Source copied below (add this to your ~/.gitconfig
file):
[alias]
pushup = "!gitbranchname() { git symbolic-ref --short HEAD; }; gitpushupstream() { git push --set-upstream origin `gitbranchname`; }; gitpushupstream"
You can also explicitly tell git pull what remote branch to pull (as it mentions in the error message):
git pull <remote-name> <remote-branch>
Be careful with this, however: if you are on a different branch and do an explicit pull, the refspec you pull will be merged into the branch you're on!
git branch --set-upstream-to=origin/master<branch_name>
You can set up a really good alias that can handle this without the overly verbose syntax.
I have the following alias in ~/.gitconfig
:
po = "!git push -u origin \"$(git rev-parse --abbrev-ref HEAD)\""
After making a commit on a new branch, you can push your new branch by simply typing the command:
git po
I did something similar to a lot of other users but wanted to share it as an alternative since I didn't see anyone else post this.
alias gpu='git push --set-upstream origin $(git branch --show-current)'
(oh-my-zsh already has a gpu alias so edited that in .oh-my-zsh/plugins/git/git.plugin.zsh)
For those looking for an alias that works with git pull
, this is what I use:
alias up="git branch | awk '/^\\* / { print \$2 }' | xargs -I {} git branch --set-upstream-to=origin/{} {}"
Now whenever you get:
$ git pull
There is no tracking information for the current branch.
...
Just run:
$ up
Branch my_branch set up to track remote branch my_branch from origin.
$ git pull
And you're good to go
In git 2.37.0
or newer, you can tell git to automatically setup the remote. This is done with
git config --global --add --bool push.autoSetupRemote true
Then you can just write git push
and it will push to the default remote.
99% of the time I want to set the upstream to a branch of the same name, so I use this (in *nix or Git Bash):
git branch --set-upstream-to=origin/$(git branch --show-current)
It's nice because it's branch agnostic. Note the sub-command git branch --show-current
prints your current branch name, or nothing if you are detached.
Side note: I have my config set such that I can use git push -u
, so I rarely need to do this. But I still do sometimes, and it's usually when I decide I want to reset my local changes to whatever's on the remote, and at that moment I realize I previously pushed without -u. So, typically the next command I'm going to run after setting my upstream, is resetting to the remote branch:
git reset --hard @{u}
Which also happens to be branch agnostic. (Maybe I just really dislike typing in my branch name.)
oh-my-zsh's git plugin already has this aliased as gpsup
. This pushes and sets the upstream to the branch. All in one go!
I personally dig solutions that are standardized and consistent. Would recommend others to use the same alias. :)
Because git has the cool ability to push/pull different branches to different "upstream" repositories. You could even use separate repositories for pushing and pulling - on the same branch. This can create a distributed, multi-level flow, I can see this being useful on project such as the Linux kernel. Git was originally built to be used on that project.
As a consequence, it does not make assumption about which repo your branch should be tracking.
On the other hand, most people do not use git in this way, so it might make a good case for a default option.
Git is generally pretty low-level and it can be frustrating. Yet there are GUIs and it should be easy to write helper scripts if you still want to use it from the shell.
you can let git create an upstream branch automatically by running either of the following git commands
- git config --global --add push.default current
- git config --global --add push.autoSetupRemote true
You can also do git push -u origin $(current_branch)
We use phabricator and don't push using git. I had to create bash alias which works on Linux/mac
vim ~/.bash_aliases
new_branch() {
git checkout -b "$1"
git branch --set-upstream-to=origin/master "$1"
}
save
source ~/.bash_aliases
new_branch test #instead of git checkout -b test
git pull
Here is a bash alias for git push which is safe to run for every push and will automatically switch between setting upstream for the first push and then doing normal pushes after that.
alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'
Original Post
All i wanted was doing something like this:
git checkout -b my-branch
git commit -a -m "my commit"
git push
Since i didn't found a better solution, i've just created an bash alias on ~/.bashrc
:
alias push="git push -u origin HEAD"
now just doing a push
command does the job (you can add this alias on ~/.gitconfig
too with another name, such as pushup
)
I sort of re-discovered legit
because of this issue (OS X only). Now all I use when branching are these two commands:
legit publish [<branch>]
Publishes specified branch to the remote. (alias: pub
)
legit unpublish <branch>
Removes specified branch from the remote. (alias: unp
)
SublimeGit comes with legit
support by default, which makes whole branching routine as easy as pressing Ctrl-b.
There are a lot of good answers here, however, all of them require you to do something else correctly before running git pull
It certainly helps to have aliases that do things like "make git push work the way it ought to, by creating a remote branch that the local is properly tracking". However, none of that helps you when you forget to use them, or went through a different workflow.
Here is a bash function that you can use to do a pull the way it ought to work, by detecting when you don't have a remote merge target configured, but there is a branch on the remote with the same name as your local branch, and setting that branch as the merge target, then pulling.
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
}
There is apparently no supported way to override default options of git commands. Based on this answer to Define git alias with the same name to shadow original command, we can override the behavior of git push
in bash to always call git push -u
. Put the following in your ~/.bash_profile
file, and it should be equivalent to running --set-upstream every time you push.
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'
精彩评论