[git] How Do I 'git fetch' and 'git merge' from a Remote Tracking Branch (like 'git pull')

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.

This question is related to git git-pull git-merge git-fetch

The answer is


Selecting just one branch: fetch/merge vs. pull

People often advise you to separate "fetching" from "merging". They say instead of this:

    git pull remoteR branchB

do this:

    git fetch remoteR
    git merge remoteR branchB

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:

    git fetch remoteR refs/heads/branchB:refs/remotes/remoteR/branchB
    git branch -a  # to verify
    git branch -t branchB remoteR/branchB

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:

  1. The branch on the remote repo: refs/heads/branchB inside the other repo
  2. Your remote-tracking branch: refs/remotes/remoteR/branchB in your repo
  3. Your own branch: refs/heads/branchB inside your repo

Remote-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 your refs/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 defines branch.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

    git pull remoteR branchB

nor

    git fetch remoteR branchB

would move refs/remotes/branches/branchB, and the latter certainly cannot move refs/heads/branchB. However, both move FETCH_HEAD. (You can cat any of these files inside .git/ to see when they change.) And git merge will refer to FETCH_HEAD, while setting MERGE_ORIG, etc.


Are you sure you are on the local an-other-branch when you merge?

git fetch origin an-other-branch
git checkout an-other-branch
git merge origin/an-other-branch

The other explanation:

all the changes from the branch you’re trying to merge have already been merged to the branch you’re currently on.
More specifically it means that the branch you’re trying to merge is a parent of your current branch

if you're ahead of the remote repo by one commit, it's the remote repo that's out of date, not you.

But in your case, if git pull works, that just means you are not on the right branch.


these are the commands:

git fetch origin
git merge origin/somebranch somebranch

if you do this on the second line:

git merge origin somebranch

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?


Examples related to git

Does the target directory for a git clone have to match the repo name? Git fatal: protocol 'https' is not supported Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) git clone: Authentication failed for <URL> destination path already exists and is not an empty directory SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 GitLab remote: HTTP Basic: Access denied and fatal Authentication How can I switch to another branch in git? VS 2017 Git Local Commit DB.lock error on every commit How to remove an unpushed outgoing commit in Visual Studio?

Examples related to git-pull

Trying to pull files from my Github repository: "refusing to merge unrelated histories" Git pull - Please move or remove them before you can merge There is no tracking information for the current branch How to unmerge a Git merge? Git: How to pull a single file from a server repository in Git? Why does git say "Pull is not possible because you have unmerged files"? fatal: could not read Username for 'https://github.com': No such file or directory Difference between git pull and git pull --rebase Is it possible to pull just one file in Git? How do I ignore an error on 'git pull' about my local changes would be overwritten by merge?

Examples related to git-merge

Abort a Git Merge Git pull - Please move or remove them before you can merge Git: How configure KDiff3 as merge tool and diff tool Git: How to pull a single file from a server repository in Git? How to resolve git error: "Updates were rejected because the tip of your current branch is behind" error: Your local changes to the following files would be overwritten by checkout Please enter a commit message to explain why this merge is necessary, especially if it merges an updated upstream into a topic branch How to merge specific files from Git branches git remove merge commit from history The following untracked working tree files would be overwritten by merge, but I don't care

Examples related to git-fetch

Trying to pull files from my Github repository: "refusing to merge unrelated histories" Git: How to pull a single file from a server repository in Git? Why does git say "Pull is not possible because you have unmerged files"? Git removing upstream from local repository The following untracked working tree files would be overwritten by merge, but I don't care Is it possible to pull just one file in Git? Retrieve specific commit from a remote Git repository fetch in git doesn't get all branches Git fetch remote branch What does FETCH_HEAD in Git mean?