I have set up some remote tracking branches in git, but I never seem to be able to merge them into the local branch once I have updated them with 'git fetch'.
For example, suppose I have remote branch called 'an-other-branch'. I set that up locally as a tracking branch using
git branch --track an-other-branch origin/an-other-branch
So far, so good. But if that branch gets updated (usually by me moving machine and commiting from that machine), and I want to update it on the original machine, I'm running into trouble with fetch/merge:
git fetch origin an-other-branch
git merge origin/an-other-branch
Whenever I do this, I get an 'Already up-to-date' message and nothing merges.
However, a
git pull origin an-other-branch
always updates it like you would expect.
Also, running git diff
git diff origin/an-other-branch
shows that there are differences, so I think I have my syntax wrong.
What am I doing wrong?
EDIT [2010-04-09]: I have checked a couple of times, and I'm definitely not on a different branch. Should my 'git fetch' followed by a 'git merge' (as shown above) do the exact same thing as a git pull? I will get some workflow showing the results of a git status etc.
these are the commands:
if you do this on the second line:
it will try to merge the local master into your current branch.
The question, as I've understood it, was you fetched already locally and want to now merge your branch to the latest of the same branch.
Git pull is actually a combo tool: it runs git fetch (getting the changes) and git merge (merging them with your current copy)
Are you sure you are on the correct branch?
Selecting just one branch:
fetch
/merge
vs.pull
People often advise you to separate "fetching" from "merging". They say instead of this:
do this:
What they don't mention is that such a fetch command will actually fetch all branches from the remote repo, which is not what that pull command does. If you have thousands of branches in the remote repo, but you do not want to see all of them, you can run this obscure command:
Of course, that's ridiculously hard to remember, so if you really want to avoid fetching all branches, it is better to alter your
.git/config
as described in ProGit.Huh?
The best explanation of all this is in Chapter 9-5 of ProGit, Git Internals - The Refspec (or via github). That is amazingly hard to find via Google.
First, we need to clear up some terminology. For remote-branch-tracking, there are typically 3 different branches to be aware of:
refs/heads/branchB
inside the other reporefs/remotes/remoteR/branchB
in your reporefs/heads/branchB
inside your repoRemote-tracking branches (in
refs/remotes
) are read-only. You do not modify those directly. You modify your own branch, and then you push to the corresponding branch at the remote repo. The result is not reflected in yourrefs/remotes
until after an appropriate pull or fetch. That distinction was difficult for me to understand from the git man-pages, mainly because the local branch (refs/heads/branchB
) is said to "track" the remote-tracking branch when.git/config
definesbranch.branchB.remote = remoteR
.Think of 'refs' as C++ pointers. Physically, they are files containing SHA-digests, but basically they are just pointers into the commit tree.
git fetch
will add many nodes to your commit-tree, but how git decides what pointers to move is a bit complicated.As mentioned in another answer, neither
nor
would move
refs/remotes/branches/branchB
, and the latter certainly cannot moverefs/heads/branchB
. However, both moveFETCH_HEAD
. (You cancat
any of these files inside.git/
to see when they change.) Andgit merge
will refer toFETCH_HEAD
, while settingMERGE_ORIG
, etc.Are you sure you are on the local
an-other-branch
when you merge?The other explanation:
But in your case, if
git pull
works, that just means you are not on the right branch.You don't fetch a branch, you fetch an entire remote: