What’s the Difference Between git fetch and git pull?
Software developers regularly use git fetch and git pull to manage work on local and remote copies of a project. Both git methods download data from the remote repo to your local version but have different functions and possible side effects. To use these commands safely and effectively we must know the differences between git fetch and git pull.
Crash Course on Local vs. Remote Repos
Git is a distributed version control system. There are two components to this definition. The first component is the version control system which refers to a system in which changes to the content are tracked with version designations. The most basic unit of change for git is the commit, and each of these commits has a unique hash that can be used to determine the software’s version.
The second part of this git definition is distributed. With git, developers are not working off the same server that stores the git repo (remote server). Instead, each developer has their own local version of the project repository that they work on. When developers finish work, they push changes to the remote or shared repository. Other developers can then integrate these changes into their own local repositories.
Git’s distributed versioning allows for clarity of who did what work and when. It also allows many developers to work on the same code simultaneously.
The remote repo is the source of truth for the project code. All developers download a version of the remote repo onto their machine to create their local repo. The local repo is a snapshot of the remote repo.
To share code changes made on a local repo, the developer must push their changes onto the remote repo and reconcile any issues. These issues arise when changes have been made to the remote repo since the last time the developer got their snapshot of the codebase.
What is git fetch?
The git fetch command downloads objects and refs from another repository. We will not dive into the 3 types of git objects in this article, but I will say there are different units of change between existing and new code. If you want to learn more about git object types check out this video.
Git fetch is considered a safe operation because it downloads copies of the remote branches of a repository without integrating changes or altering your local work. This command is a good way to see what is happening on the remote repository without changing your local copy of the repository.
After you have done a git fetch, you will have a special FETCH_HEAD file containing the latest commit or HEAD commit for each of the downloaded branches from the remote repository. A commit consists of changed code from the last commit and the SHA hash of the previous commit. Your local system can trace back all work completed on each branch using the branch’s HEAD commit.
You are not trying to update your local branches directly with git fetch. Instead, you pull down a status report of what is happening remotely to inform you how to proceed with your local code. To pull the changes from the remote repo into your local branches you must fetch and then integrate the changes. This is where git pull comes in.
What is git pull?
While git fetch is safe as it only downloads what is happening on the remote branches of your repository, git pull takes this a step further. Get pull fetches from and integrate with another repository or a local branch. It can be seen as combining two commands: git fetch and git merge.
First, git pull will fetch the remote version of your branch. As with the more general git fetch command, this downloads the changes from the remote branch to update the local version of the remote branch. It goes a step further than git fetch by attempting to merge the remote version of the branch with your current local version.
This is not a safe operation as it consists of a read (adding the latest remote version of a branch to your local environment) and a write (integrating the remote changes with your local branch and work). When we git pull a branch we integrate the remote work with our current code.
If this is only adding commits to move the head forward (a fast-forward operation) then we should not have issues. However, if we are ahead on commits (commits exist locally that do not exist on the remote) we may have a merge conflict that we will have to resolve when integrating into remote work.
Git pull is a more active command as we perform some write operations on our local code. It is more intentional as we can not simply discard remote changes after we call to pull them into our local code.
Good Practice for Using These Methods
There are ways to make working with git fetch and git pull easier. With git fetch, you are reading remote changes to update your local snapshot of the remote branches. There is not a lot that can go wrong with this other than the download process being interrupted.
We can do more to prepare for git fetch as the differences between our local and remote branches can cause issues here. If you have uncommitted changes locally on a branch, you may want to stash them before doing a git pull. This will allow you to perform a fast-forward operation without creating issues on the local branch.
Conflicts may arise when you pop your stashed changes, but you will not face an immediate merge conflict when pulling remote changes locally. At some point, you will have to resolve differences, but stashing changes before you pull from the remote will allow you to view and test the remote version first.