Git fetch + merge, Git fetch + rebase, Git pull

Few days back, Amitoj asked me why doesn’t git fetch deletes the changes that are not present on remote but are present in local, when it does updates other changes. To explain it one need to understand the difference between git fetch + merge, git fetch + rebase and git pull and why we need to merge or rebase after a fetch and when? I tried searching for some good resources to explain the difference but I didn’t find anything good. So I thought of writing one.

First of all have a look at this image by  Oliver Steele.


Let’s understand everything one by one.


Git fetch

It fetches the commits from the target branch which are not present in your current branch and stores them in your local. Remember it fetches and keeps, it does not merge those changes. This helps you to keep your local updated but not break anything if you are working on something which might break things if you update (merge) your changes. In terms of folders git fetch only updates the .git/ directory (local) and nothing outside .git/ (the working tree). It does not change your local branches, and it does not touch master. It touches remotes/origin/master.

In simple words if updates your local copy of the remote repository.


Git merge after git fetch

It does what you are missing above. As they say it is used to join two lines of history. It can be the case that you or the remote didn’t do any change since the last merge base then git either, fast-forward(your branch is updated to the remote branch) or it says you are up-to-date (nothing new to merge).

So if you want to delete those files that were still present in your local, do a git merge after fetch, it will.


Git rebase after git fetch

As the two cases above have git fetch as common. The thing we need to understand is the difference between git rebase and git merge.

When you rebase [3] it rewrites the history (whereas merge doesn’t). It makes it look like that you have committed on top of origin’s new master branch  instead of where you were actually committing. As it changes the history, it is suggested that you should not ideally rebase if it a public branch on your own private branch you can.


Git pull

In simple terms git pull is git fetch + git merge. An alternative. It updates your local with its remote version, and also updates your other remote-tracking branches. It merges to your current branch. It automatically does all the work. You can’t review any new change that is being merged.

For more

  1. Git scm docs
  2. Git kernel docs

One Reply to “Git fetch + merge, Git fetch + rebase, Git pull”

  1. Hi,
    I’ve noticed in the past that git pull and {git fetch && git merge FETCH_HEAD} do very different things. In particular, merging(pull) vs not merging(fetch + merge).

    tl; dr (but please do)

    E.g. fetch + merge will say up-to-date but pull does the merge you’d expect. I realize that there are situations where, e.g. fetch+merge (hereinafter fnm) says up-to-date and diff shows all the diffs you’d expect to be merged. This case has been explained, however, I can’t find a reason for the pull vs fnm. They may have the same root cause, but pull is doing something different (i.e. working) and fnm isn’t. *Everything* I’ve seen on the web (on which everything is true and fake at the same time… must be a superposition) says pull is the same as fnm. There are no conditions applied. So, if possible, can you tell me what pull does differently and what the ramifications are?

    PS: the email address is real. Domain mailboxes make things so much easier to manage. The website is far from real.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s