Git: Discard All Local Changes and Pull the Latest Remote Version
To discard all your local changes and pull the latest version from a GitHub repository, you need to completely reset your local branch to match the remote's state. This process removes all uncommitted and committed local changes.
This guide covers the most reliable methods, including situations where you want to preserve specific local files like .gitignore or clean up untracked files.
Method 1: The Safest & Cleanest Way (Fetch & Hard Reset)
If you have already made one or more local commits or uncommitted edits that you want to completely discard, you need to use git reset. The --hard flag tells Git to reset your branch pointer and wipe out all changes from your working directory and staging area.
Step 1.1: Fetch the Remote State
A common mistake is running git reset --hard without running git fetch first. This only resets your branch to the last time you fetched, not the absolute latest version on GitHub.
git fetch origin
This command downloads the latest changes from the remote repository without merging them into your local branch.
Step 1.2: Forcefully Reset to Remote
Now, reset your local branch to match the remote branch (replace main with dev or your branch name if different):
git reset --hard origin/main
Using git fetch followed by git reset --hard is the safest, most explicit, and most reliable method for discarding all local changes and synchronizing with the remote. It leaves no room for merge conflicts.
Method 2: Discarding ONLY Uncommitted Changes
If you have local modifications in your working directory that you haven't committed yet and want to throw away, you can use git restore (or the older git checkout command):
# Discard all changes in the current working directory
git restore .
# (Older Git versions) Discard all changes in the working directory
git checkout -- .
After running this, your working directory will be clean, and all your local uncommitted modifications will be gone.
Method 3: Resetting While Preserving Specific Local Files (e.g., .gitignore)
Sometimes you want your local repository to match the remote, but you want to preserve specific local files (like a custom .gitignore or local configuration files) that are not pushed to GitHub. You can do this by temporarily stashing them before the reset:
Step 3.1: Stash your target file
git stash push -- .gitignore
This adds .gitignore to your stash, a temporary storage area.
Step 3.2: Fetch and Reset
git fetch origin main
git reset --hard origin/main
Step 3.3: Clean Untracked Files
git clean -d -f
The -d flag removes untracked directories, and -f forces the operation. git clean respects .gitignore, so it won't delete files that are ignored.
Step 3.4: Restore the preserved file
git stash pop
This applies the stashed .gitignore back into your working directory.
The git pull --force Alternative (Not Recommended)
Some developers try to run git pull --force to override local changes. However, this is not the right tool for the job. The purpose of git pull is to integrate changes, not to discard them. Forcing a pull can lead to unexpected merge conflicts or an unmanageable commit history.
Summary of Commands
| Command | Purpose | When to Use |
|---|---|---|
git fetch origin | Downloads the latest remote state without merging. | Always run this first for a full reset. |
git reset --hard origin/main | Forcefully discards local commits and uncommitted changes. | The core command to completely wipe your local branch. |
git restore . | Discards uncommitted changes in your working directory. | When you just want to revert uncommitted files. |
git clean -d -f | Forcefully removes untracked files and directories. | To clean up workspace junk after resetting. |
