简体   繁体   中英

Does git fetch <remote> fetch it for all the local branches tracking that remote?

If I have multiple local branches tracking a remote branch foo , does

git fetch foo

fetch foo for all the local branches that track it or just the one I am in at the time of the fetch?

IOW, if I switch to another branch that tracks the same remote, do I still need to fetch the remote after I did it immediately before in the other branch?

I found this thread that is remotely related but I think it means that the --all in git fetch --all means fetch all remotes and not fetch the one remote the current local tracks for all the local branches it tracks.

If you have several local branches tracking the same one then fetch will fetch for all of them, or the one, as it's really just one remote branch.

Say your remote branch is devel then it will be named origin/devel locally and all your local branches will track origin/devel , the one and only.

So for your local branches you only need to do git rebase origin/devel after a git fetch origin to have it updated. All local branches will have it's upstream at the exact same commit.

This is already answered and accepted but I'll add this anyway: git fetch remote takes everything the named remote is willing to give you based on the "refspec" arguments. With no refspec, it uses the refspecs given in fetch = lines for that particular remote.

The default refspec, if you have not configured any, is:

fetch = +refs/heads/*:refs/remotes/origin/*

assuming the name of the remote is origin (which is also the default, usually). 1

You can think of the two git sessions (yours, doing git fetch , and the one on the remote that supplies data) as having a sort of telephone conversation. Yours calls up theirs and asks it for a list of all its references, and the SHA-1 IDs that go with them. Theirs might say "I have branch master and branch devel" (with some SHA-1s) "and tags v1.0 and v1.1" (with more SHA-1s).

At this point, your fetch goes through the list they gave you and picks out the names and SHA-1s it wants. They will go through some more conversation as needed, to select all the underlying repository objects needed to complete the objects that go with those SHA-1s ("commit" SHA-1s need "tree" SHA-1s which need more trees and/or "blobs"; but you may already have some, most, or all of them). Then they send over all the SHA-1-identified repository objects, and your fetch stashes them in your repo.

Finally, your fetch updates your copy of their reference-names, using those same refspecs. With the standard one for origin , this means that each of their branches—each name under refs/heads/ in their repository—gets a corresponding name in your repository, but listed under refs/remotes/origin/ instead. So your repository now has every branch they had when the "phone conversation" started, but in your repo, these are listed as a "remote branch" under origin/ .

If you already have the name, fetch needs to know what to do if the associated SHA-1 has changed. For instance, their refs/heads/master might point to a different commit SHA-1 now. There are special fast-forward rules for branches, 2 but the main thing to know is that the + at the front of a refspec means "forced update": the + in +refs/heads/*:refs/remotes/origin/* means "update them all, no matter what". Without the + , some reference-names may be left pointing to the original reference.

If you add --tags to your git fetch , this has the effect of adding refs/tags/*:refs/tags/* to the refspec set. This brings over all tags—into your (single, global) tag namespace under refs/tags —but without forced-update, so that if you already have a tag like amphibient-save , their tag with the same name will be ignored. (If your Git is 2.19 or later, see VonC's footnote; I have not tested this yet.)

This boils down to: "by default, git fetch brings over all branches and all useful tags". However, the specifics are useful to know, especially in edge cases.


1 There is a special hack for tags : if you have not specifically asked your fetch to bring over all tags, but you have asked for branches—again, this is the default—it looks to see which, if any, tag references go with branches you're bringing over, and your fetch then updates your tags with those tags, as if you'd listed refs/tags/ tag :refs/tags/ tag . As with --tags , this is a "non-forced" update.

2 Non-forced tag updates used to follow the non-forced branch update rules of allowing the update if and only if the update is a fast-forward. This behavior changed as of git version 1.8.2; tags now update only if forced, regardless of fast-forward.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM