What does git fetch and git pull actually do?

Sivasubramanian S
3 min readFeb 20, 2024

--

First, you need to understand how the git directories are split into itself. Imagine there are four parts, the left-most being the Working Directory -> Staging Area -> Local Directory -> Remote Repository.
Work arounds on these terms :
- Working Directory is where the current branch you have worked or are working on resites.
- Staging Area is the place where all the changesets which were added resites. Changesets are staged here before we commit it.
- Local Directory is where all the commits made is placed. Usually Local directory stays in sync with the commits present in Working Directory.
- Remote Repository is where the the commits made to Local directory is pushed.

Lets now see what a GIT PULL does?

When we pull from a branch, the commits of the branch’s Remote Repo gets synced to the Local and working directory.

Then, what a GIT FETCH do?

When we run the fetch command from any branch of a repo, all the branches or commits which are present in the Remote Repo gets synced to the Local Directory. We can now checkout to any of the branch that were present in the Remote repo. On doing this, exclusively the commits from the Local directory of that particular branch gets synced to the Working Directory.

Wait … That’s not the only point of sharing this post. The core of the post is to explain what does the equation below convey!

FETCH + MERGE = PULL.

GIT MERGE operates in two different ways based on the scenario. One is to just fast-forward i.e. it will get the commits synced from Local and move the head to the same position as the Local repository. This will only happen if the commits history of Working Directory matches with that of Local Directory (no additional commits were made onto the base branch). The other way is where the commits history does not match. In this case, we need to decide and perform the merge manually which results into creation of a new merge commit.

Here’s the catch when we run the fetch command, it’s expected to sync the commits from the remote to the local repo and once we checkout to that branch the commits should get synced to the working directory. But this does NOT happen when we have already checked out to the branch and then trying to fetch the commits for it. In this case the commits will be synced to local but not to working directory even if we check-out to that branch. To get the local and working directory synced we need to run MERGE command. This can simply be acheived by just running PULL. Literally here the FETCH + MERGE = PULL turns intentional.

There is a diff in performing FETCH and PULL individually. Running a FETCH command will fetch all the commits of the repo from which you are running the command and syncs it to the Local directory. On the other side, PULL does FETCH the commits of the particular branch (NOT commits of the entire repo) which is then synced to Local directory and MERGEd to the Working directory.

This image will give a clear representation of GIT PULL :

What tends to go around when we do a Git PULL?

Initial Stage : Describes the commits in the branch-A.

Step 1 : Here we are in Working Directory and pull from the branch-A whose HEAD is currently pointed to commit-C.

Step 2 : Git FETCHes the commits of the branch-A from remote repo and syncs it to the Local Directory.

Step 3 : Now, the Local Directory’s branch-A HEAD points to the commit-J as in the Remote Repo.

Step 4 : Then, An Auto packing will be initiated where basically the Git MERGE command will be executed over the branch-A’s Local Directory.

Step 5 : Here >>Fast -Forward>> happens as the history of the Working Directory matches with the History of the LocalDirectory. History of commits here is referred to the commits-A,B,C which are the same in Local and Working Directory. History is compared by taking the HEAD of Working Directory’s branch-A to the history of Local Directory.

--

--

Sivasubramanian S

Updates on my learnings that can help grow as a developer.