gitgit-branchgit-pullgit-fetch

Why do I have to run "git branch --set-upstream-to=origin/<branch> local-branch-name" while doing git pull?


I am wondering why I have to git branch --set-upstream-to=origin/<branch> local-branch-name when doing git pull? Is there a way to keep the upstream the same as the current local branch of local-branch-name?

Here is what I do:

$ git branch | grep "*"
local-branch-name
$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to rebase against.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> local-branch-name

$ git branch -r | grep local-branch-name
  origin/local-branch-name   # the local-branch-name can be found in the remote


Solution

  • The reason why you need to associate a remote's branch to your local branches whenever you're performing your first git pull, or when you keep pulling into disassociated branches, might be because your repository's config is missing the fetch refspec under the remote's configuration.

    [remote "<name>"]
            url = <URL>
            pushurl = <pushurl>
            push = <refspec>
            fetch = <refspec>
    

    To fetch each branch from the remote into a local tracking branch with the same name, your fetch refspec should be configured like so:

    [remote "origin"]
        url = <URL>
        fetch = +refs/heads/*:refs/remotes/origin/*
    

    At this point, you can perform git pull for any branch of your repository without having to perform a git branch --set-upstream-to first. The operation will always fetch changes from a remote's branch into a tracking branch with the same name. However, make sure to always be on the right branch before pulling. A git pull is just a git fetch followed by a git merge, therefore, even though you might be fetching into the desired tracking branch, you could be merging into the wrong local branch.


    Also, keep in mind that even though a remote's branches have a certain name, it's not mandatory for your local repository to share the same name of its remote counterpart. In fact, you could have on your remote a branch called dev, while the same branch on your local repository could be called feat. In this case, you might want to define multiple refspec for the remote, where each one of them describes a specific association.

    [remote "origin"]
        url = <URL>
        fetch = +refs/heads/dev:refs/remotes/origin/feat
        fetch = +refs/heads/master:refs/remotes/origin/master