Skip to main content

Git Pull Force: How to Overwrite a Local Branch With Remote

Learn why git pull --force isn’t the best way to overwrite a local branch with the remote version, and discover the proper method using git fetch and git reset.
Aug 6, 2024

In certain situations, we may wish to reset the state of a local Git branch to align it with the remote repository, thereby discarding any local changes. This is commonly referred to as a forced pull.

This creates the misconception that the way to archive this is to use the --force option in the git pull command. In this article, we learn that these are different things.

If you're new to Git, consider reading our Git push and pull tutorial first.

We can overwrite our local state with the remote state by using the commands listed below, substituting <branch_name> with the name of your branch. This action will permanently delete all your local changes in that branch.

git fetch
git reset --hard origin/<branch_name>

This article will delve into the details of how these commands work. We go beyond quick fixes to understand the underlying mechanics, thereby learning more effective methods to achieve the desired outcome without the risk of losing important changes. We also clear the misconception and learn what the --force option of git pull actually does.

Become a Data Engineer

Build Python skills to become a professional data engineer.
Get Started for Free

When to Consider Overwriting Local Changes

In general, overwriting local changes in this way goes against the intended usage of Git. For almost any situation, there’s a proper Git workflow to solve it. However, some of these often require a deeper understanding of Git and take more time to execute. Even if it’s not a best practice, overwriting local changes can sometimes be the fastest way to get work done.

For me, this usually happens when I work on a feature that I’m not very familiar with. I start by creating a branch and making a few commits. When I get stuck, I ask a colleague for help. They begin from an earlier commit, before I made the mistake, resolve the issue, and push their changes. At this point, I need to replace my local version with the updated remote version while discarding my local changes, so I can continue working on the feature.

Another example is when there’s a conflict, and I feel it’s harder or more time-consuming to fix the conflict than to re-implement our changes on the latest version of the code.

Regardless of the reason, always make sure that those changes really aren’t necessary and can safely be deleted or to back up your branch to avoid losing important work.

How to Overwrite Local Changes Correctly

The first step is to fetch (download) the latest content from the remote repository on our local machine. This is done using the fetch command from git:

git fetch

By default, this will fetch the contents of the current branch which is usually what we need. We can optionally specify the branch we wish to download (replacing <branch_name> below with the name of the branch we want to fetch):

git fetch origin/<branch_name>

Alternatively, we can use the --all option to download everything:

git fetch –all

Fetching the changes from the remote repository will not affect the files in your current working branch directory. The fetch command downloads the changes from the remote repository but doesn't merge them. The local repository keeps a view of both the local files and the remote files, and fetching updates the view of the remote files.

After downloading the changes from the remote repository, we can use the reset command from git to reset the current working branch into a given state:

git reset --hard origin/<branch_name>

The --hard option is required to make sure that the local changes are overwritten by the remote changes. In the command above, we chose to replace the current working branch with origin/<banch_name> which corresponds to the remote version of that branch that was just fetched.

The git reset command will delete local changes, even if they’re committed. It is, therefore, recommended to create a local backup of the current branch before executing that command. This can be done using:

git branch <name_of_the_backup_branck>

Replacing <name_of_the_backup_branch> with the name you want the backup branch to have.

Putting it all together, we can override all local changes from a given branch with the latest remote version by doing the following:

git fetch
git branch <name_of_the_backup_branch>
git reset --hard origin/<branch_name>

If you'd like to expand your knowledge on working with branches in Git, check out the Git Clone a Specific Branch tutorial.

Full cleanup by deleting untracked files

Git will not touch untracked files (files that were never using git add). If we also want to delete these files, we can do it using:

git clean -fdx

This is a dangerous command that is used to remove untracked files from the working directory. It is essential to use this command with caution because it permanently deletes these files, making it impossible to recover them through Git. Here's a breakdown of the command options:

  • -f: This option forces the clean operation to proceed. Git will refuse to delete untracked files from the working directory without this flag as a safety measure to prevent accidental data loss.
  • -d: This tells git clean to remove not just untracked files but also untracked directories. By default, git clean targets only untracked files and ignores directories.
  • -x: By default, git clean will respect the .gitignore rules and not remove files or directories that match these patterns. Including -x overrides this behavior, instructing Git to also remove the files/directories that are ignored by .gitignore or other ignore rules. This results in a very thorough cleaning, removing all untracked files in the repository, including build outputs, log files, and other generated artifacts that are typically ignored.

Understanding Git Pull

The usual way we update our local repository with remote changes is by using the git pull command. However, this command cannot be used to override our local changes because git pull will try to merge our local version with the remote.

Under the hood, git pull performs the following steps:

  1. It uses git fetch to download the latest version of the remote repository.
  2. It uses git merge to merge the local and remote branches.

Because of the merge step, git pull isn’t a suitable command in situations where we want to ignore and discard local changes.

<code data-mce-selected=

How about the git pull --force?

By looking at the documentation of the git pull command we see that it offers a --force option. It is a common misconception that this option will force the git pull command to execute by erasing the local changes with the remote changes.

When we provide the --force option to git pull, this option is passed down to git fetch. Thus git pull --force performs the following steps:

  1. git fetch --force
  2. git merge

 <code data-mce-selected=

We learned that fetch is used to update the local view of the remote repository. If the only difference between your current local repository and the remote repository is some missing commits (the local branch is behind the remote version), then git fetch will simply update the local view by appending those new commits to the history.

Git fetch syncs the local repository with the remote repository if the branch history matches

However, it could be the case that someone rewrote the commit history of the remote branch making it incompatible with the local view. In this case, fetch won’t work.

Git fetch will fail if the branch history doesn't match unless we use the <code data-mce-selected=

We can get around this using the --force option which will force Git to ignore the local history and overwrite it with the remote history. 

We see that the --force option is related to forcing commit history overwrite and has nothing to do with ignoring local changes in the working branch directory.

Integrating Local Changes

Overwriting the local changes with the remote changes is not a common Git practice but can be useful in certain cases where we don’t want to deal with conflicts or don’t care about our local changes.

Merging

Usually, one would pull the changes and deal with the conflicts. People tend to be scared to deal with conflicts. Some conflicts can be overwhelming to deal with, but that’s not often the case. A conflict occurs when:

  1. Both the local branch and the remote branch have changes on the same part of a file.
  2. A file is deleted on one side and modified on the other.

In these cases, Git cannot guess which changes we want to keep, and we need to let it know manually. Git will highlight the conflict in the files like so:

Git conflicts example

To resolve a conflict, we edit the file by deleting these lines except the ones we want to keep. After handling all of the conflicts, we can commit the changes. For an in-depth guide, check out this tutorial on how to resolve merge conflicts in Git.

Cherry-picking

If we really want to first make our local version match the remote version and then eventually integrate our changes, we can bring the commits from the backup branch into the current branch, like so:

git cherry-pick <commit_hash>

Here, <commit_hash> is the hash of the commit we want to integrate. This assumes that before doing git reset, we created a backup branch with git branch <name_of_the_backup_branck> and that the local changes had been committed.

To find the <commit_hash>, we can list the commit hashes in the backup branch using the following command:

git log <name_of_the_backup_branck>

Stashing

Alternatively, if we don’t want to commit our changes or create a backup branch, we can stash our changes before merging using:

git stash

This command can be used to temporarily save the current work without committing it to the branch history. Stashing sets aside your modifications, allowing you to have a clean working directory.

After resetting, we can bring out changes back using the following command:

git stash pop

Using stashing, the whole workflow would look something like this:

git fetch
git stash
git reset --hard origin/<branch_name>
git stash pop

To learn more, check out this cheat sheet with stash and other git commands.

Conclusion

Despite not being a best practice, sometimes we find ourselves in a situation where we just want to make our local branch match the contents of the remote branch while discarding our local changes.

There’s a misconception that this is achieved using git pull --force. This is incorrect because git pull --force combines git fetch --force and git merge. Therefore, it attempts to merge the local changes with the remote changes, not overwriting them.

The correct way to overwrite local changes with the contents of the remote repository is:

git fetch
git reset --hard origin/<branch_name>

The git reset command must be used with caution because it will delete local changes, even if they have been committed. If we had local commits and created a backup branch, we can bring them back using git cherry-pick. If we didn’t commit and want to temporarily save our local work we can use git stash before resetting and then git stash pop to bring our changes back.

Get certified in your dream Data Engineer role

Our certification programs help you stand out and prove your skills are job-ready to potential employers.

Get Your Certification
Timeline mobile.png

Photo of François Aubry
Author
François Aubry
LinkedIn
Teaching has always been my passion. From my early days as a student, I eagerly sought out opportunities to tutor and assist other students. This passion led me to pursue a PhD, where I also served as a teaching assistant to support my academic endeavors. During those years, I found immense fulfillment in the traditional classroom setting, fostering connections and facilitating learning. However, with the advent of online learning platforms, I recognized the transformative potential of digital education. In fact, I was actively involved in the development of one such platform at our university. I am deeply committed to integrating traditional teaching principles with innovative digital methodologies. My passion is to create courses that are not only engaging and informative but also accessible to learners in this digital age.
Topics

Learn more about Git!

course

Introduction to Git

4 hr
38.1K
Familiarize yourself with Git for version control. Explore how to track, compare, modify, and revert files, as well as collaborate with colleagues using Git.
See DetailsRight Arrow
Start Course
See MoreRight Arrow
Related

tutorial

Git Rename Branch: How to Rename Local or Remote Branch

Learn how to rename local and remote Git branches using either the terminal or the graphical user interface (GUI) of popular clients like GitHub.
François Aubry's photo

François Aubry

5 min

tutorial

GIT Push and Pull Tutorial

Learn how to perform Git PUSH and PULL requests through GitHub Desktop and the Command-Line.

Olivia Smith

13 min

tutorial

Git Clone Branch: A Step-by-Step Tutorial

To clone a specific branch, use the command git clone --single-branch --branch , replacing with the desired branch and with the repository's URL.
François Aubry's photo

François Aubry

tutorial

How to Clone a Specific Branch In Git

Learn how to clone only a single branch from a Git repository to save disk space and reduce cloning time.
Bex Tuychiev's photo

Bex Tuychiev

6 min

tutorial

How to Resolve Merge Conflicts in Git Tutorial

Learn various commands and tools for merging two branches and resolving conflicts in Git, an essential skill for data scientists.
Abid Ali Awan's photo

Abid Ali Awan

16 min

tutorial

Git Reset and Revert Tutorial for Beginners

Discover how to use Git reset and revert to manage your project history. Practice with detailed examples using soft, mixed, and hard resets. Learn the difference between Git reset and revert.
Zoumana Keita 's photo

Zoumana Keita

10 min

See MoreSee More