[git] Why do I need to do `--set-upstream` all the time?

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 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?

This question is related to git git-branch

The answer is


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.


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.


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

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

You can also do git push -u origin $(current_branch)


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.


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

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


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.


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"

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 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.


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

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


git branch --set-upstream-to=origin/master<branch_name>

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.


By the way, the shortcut to pushing the current branch to a remote with the same name:

$ git push -u origin HEAD

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!