Search code examples
gitgit-pullgit-configgit-fetchremote-branch

Why does `git pull` pull 1000s of remote branches to my local?


When I do git pull it fetches all remote branches to my local. And it saves them as remote-tracking branches (this is not the issue, though). I think it also fetched tags and maybe other things too.

I did (git branch -r).Length and got about 2500 whereas before it was a lot less.

Is this because of some config setting/value?

How can I prevent this? If I am on branch foo, I just want git pull to fetch changes from remote branch foo and nothing else. I.e.:

  • If I am on a branch foo tracking remote-tracking branch origin/foo, then I want git pull / git fetch to only fetch just the changes from the remote branch origin foo.

  • If I am on a branch bar that is not tracking any remote-tracking branch, then I want git pull / git fetch to do nothing -- or maybe just notify me that this branch is not tracking any branches from which to fetch.

How can I induce this behavior?


In PowerShell, I did git config list --show-scope | sls "fetch|pull" and summarized the output in the table below

| file   | name                | value                                               |
|--------|---------------------|-----------------------------------------------------|
| system | pull.rebase         | false                                               |
| local  | pull.rebase         | true                                                |
|        |                     |                                                     |
| local  | remote.origin.fetch | +refs/heads/dev/jv/*:refs/remotes/origin/dev/jv/*   |
| local  | remote.origin.fetch | +refs/heads/feature/*:refs/remotes/origin/feature/* |
| local  | remote.origin.fetch | +refs/heads/hotfix/*:refs/remotes/origin/hotfix/*   |
| local  | remote.origin.fetch | refs/heads/master:refs/remotes/origin/master        |

What does remote.origin.fetch=+refs/heads/dev/jv/*:refs/remotes/origin/dev/jv/* mean? What does the + mean?

Prior to git pull, (git branch -r | sls dev/jv/).Length was 1 representing 1 remote-tracking branch.

After, it was 21 representing 21 remote-tracking branches. So 20 of these dev/jv/* branches were fetched.


Solution

  • If I am on branch foo, I just want git pull to fetch changes from remote branch foo and nothing else

    You probably shouldn't be using git pull at all. By default, git pull calls git fetch which, by default, fetches all remote branches (in your case it fetches all remote dev/jv branches), and you say you don't want that.

    Instead, just say

    git fetch origin branch-I-want-to-fetch
    

    Now you have updated origin/branch-I-want-to-fetch and can do whatever you like. If the goal is to update your local branch-I-want-to-fetch, then just get on that branch and say

    git merge
    

    A nice shortcut is to say

    git fetch origin branch-I-want-to-fetch:branch-I-want-to-fetch
    

    That fetches the branch into the remote-tracking branch and merges that into the local branch. You can do it even if you are not currently on that local branch.


    What does remote.origin.fetch=+refs/heads/dev/jv/*:refs/remotes/origin/dev/jv/* mean?

    It means that saying git fetch origin, or git fetch for short, fetches all remote dev/jv/ branches into same-named remote-tracking branches. You could rewrite this to specify that git fetch means to fetch just one specific branch, but I don't recommend that.

    What does the + mean?

    It means use force if necessary. Consider reading the docs.