How do I force "git pull" to overwrite local files?
Solution 1
⚠ Warning:
Any uncommitted local change to tracked files will be lost, even if staged.
But any local file that's not tracked by Git will not be affected.
First, update all origin/<branch>
refs to latest:
git fetch --all
Backup your current branch (e.g. master
):
git branch backup-master
Jump to the latest commit on origin/master
and checkout those files:
git reset --hard origin/master
Explanation:
git fetch
downloads the latest from remote without trying to merge or rebase anything.
git reset
resets the master branch to what you just fetched. The --hard
option changes all the files in your working tree to match the files in origin/master
.
Maintain current local commits
[*]: It's worth noting that it is possible to maintain current local commits by creating a branch from master
before resetting:
git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master
After this, all of the old commits will be kept in new-branch-to-save-current-commits
.
Uncommitted changes
Uncommitted changes, even if staged (with git add
), will be lost. Make sure to stash
or commit anything you need. For example, run the following:
git stash
And later (after git reset
), reapply these uncommitted changes:
git stash pop
Which may create merge conflicts.
Solution 2
This will remove all uncommitted changes, even if staged,
and then pull:
git reset --hard HEAD
git pull
But any local file that's not tracked by Git will not be affected.
Solution 3
WARNING: git clean
deletes all your untracked files/directories and can't be undone.
Sometimes just clean -f
does not help. In case you have untracked DIRECTORIES, -d option also needed:
# WARNING: this can't be undone!
git reset --hard HEAD
git clean -f -d
git pull
WARNING: git clean
deletes all your untracked files/directories and can't be undone.
Consider using -n
(--dry-run
) flag first. This will show you what will be deleted without actually deleting anything:
git clean -n -f -d
Example output:
Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...
Solution 4
Like Hedgehog I think the answers are terrible. But though Hedgehog's answer might be better, I don't think it is as elegant as it could be. The way I found to do this is by using fetch
and merge
with a defined strategy. Which should make it so that your local changes are preserved as long as they are not one of the files that you are trying to force an overwrite with.
First do a commit of your changes
git add *
git commit -a -m "local file server commit message"
Then fetch the changes and overwrite if there is a conflict
git fetch origin master
git merge -s recursive -X theirs origin/master
-X
is an option name, and theirs
is the value for that option. You're choosing to use their
changes (the other option is ours
changes) if there is a conflict.
Solution 5
Instead of doing:
git fetch --all
git reset --hard origin/master
I'd advise doing the following:
git fetch origin master
git reset --hard origin/master
No need to fetch all remotes and branches if you're going to reset to the origin/master branch right?