Jakub Troszok
Jakub Troszok

Reputation: 103843

How do I force "git pull" to overwrite local files?

How do I force an overwrite of local files on a git pull? My local repository contains a file of the same filename as on the server.

error: Untracked working tree file 'example.txt' would be overwritten by merge

Upvotes: 9848

Views: 9115913

Answers (30)

RNA
RNA

Reputation: 153581

⚠ 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. main):

git branch backup-main

Jump to the latest commit on origin/main and checkout those files:

git reset --hard origin/main

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/main.


Maintain current local commits

[*]: It's worth noting that it is possible to maintain current local commits by creating a branch from main before resetting:

git checkout main
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/main

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.

Upvotes: 13492

Alex Henrie
Alex Henrie

Reputation: 887

git-extras (available from your favorite package manager) has a command specifically for wiping out your local branch and replacing it with the corresponding remote branch:

git sync

Beware that it also deletes untracked files, though you can pass -s or --soft to keep them.

Upvotes: 1

Penguin
Penguin

Reputation: 411

The easiest way that some of the other answers get to in a more involved way is to just delete the file causing the issue:

rm ./some/path/to/problem/file

Then everything works fine:

git pull

Upvotes: -1

Dragos George
Dragos George

Reputation: 103

The simplest way I found was to

  1. Rename the branch to something else

  2. Checkout to the branch you want to pull and pull from origin

    git branch -m to-delete
    git checkout main
    git pull
    
  3. Finally, you can delete the old branch

    git branch -D to-delete

Upvotes: 7

leNaranFo
leNaranFo

Reputation: 19

I was trapped in a similar problem my repository was in a branch in which every file was put in asubfolder myapp/subfolder and this command works to clean history.

 git clean -f -d 

Upvotes: -1

Achraf Farouky
Achraf Farouky

Reputation: 1240

git fetch --all
git reset --hard origin/develop

Upvotes: 36

Travis Reeder
Travis Reeder

Reputation: 41123

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.

Upvotes: 1455

Michael Brenndoerfer
Michael Brenndoerfer

Reputation: 4076

The key to this is using FETCH_HEAD.

git fetch origin <your e.g. feature branch>
git reset --hard FETCH_HEAD

I've tried HEAD and git pull and none worked.

Upvotes: 8

FelipeGTX
FelipeGTX

Reputation: 111

git restore file_to_override_from_remote

git pull

Upvotes: 3

kkhhww
kkhhww

Reputation: 101

This solution is always running.

cd $GIT_ROOT_DIRECTORY
git fetch origin/$TARGET_BRANCH
git rm -rf --cached .
git reset --hard origin/TARGET_BRANCH
git clean -df
git pull origin $TARGET_BRANCH

Upvotes: 6

Frederik Bode
Frederik Bode

Reputation: 2744

For those who don't like reset, I like this approach:


git checkout branchname      # go to your branch
git fetch origin branchname  # fetch the remote
git checkout -b backup       # optionally, mark your remote as a backup
git branch -f branchname origin/branchname # force your local branch to be equal to the fetched origin/branchname


Upvotes: 3

Ahmad Ismail
Ahmad Ismail

Reputation: 13942

I am not sure why anyone did not talk about FETCH_HEAD yet.

git fetch origin master && git reset --hard FETCH_HEAD

If you want to put it in an alias, the command would be:

git config --global alias.fpull '!git fetch origin master && git reset --hard FETCH_HEAD'

Upvotes: 26

Arief Karfianto
Arief Karfianto

Reputation: 245

"My local changes was small, or my changes doesn't work. I just want to reset everything back to original. I know that all my local changes will be lost."

If that's the case then:

git reset --hard
git pull

Upvotes: 5

Nisarg Jhatakia
Nisarg Jhatakia

Reputation: 107

If you are working on your code and find the new changes a huge mistake or unwanted you can simply use an alternative like:

git restore .

where . means all the files present in the directory.

Upvotes: 6

warch
warch

Reputation: 2609

Here is a generic solution if you do not always want to paste the branch name or you want to automate this within a script

git fetch
git reset --keep origin/$(git rev-parse --abbrev-ref HEAD)

If you want to reset your local changes too:

git fetch
git reset --hard origin/$(git rev-parse --abbrev-ref HEAD)

You also could add a bash alias using this command:

alias gplf='git fetch && echo "HEAD was at $(git rev-parse --short HEAD)" && git reset --hard origin/$(git rev-parse --abbrev-ref HEAD)'

Upvotes: 53

Strahinja Kustudic
Strahinja Kustudic

Reputation: 4472

The problem with all these solutions is that they are all either too complex or, an even bigger problem, is that they remove all untracked files from the webserver, which we don't want since there are always needed configuration files which are on the server and not in the Git repository.

Here is the cleanest solution which we are using:

# Fetch the newest code
git fetch

# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge origin/master')
git pull
  • The first command fetches the newest data.

  • The second command checks if there are any files that are being added to the repository and deletes those untracked files from the local repository which would cause conflicts.

  • The third command checks-out all the files which were locally modified.

  • Finally, we do a pull to update to the newest version, but this time without any conflicts, since untracked files which are in the repo don't exist anymore and all the locally modified files are already the same as in the repository.

Upvotes: 72

joelostblom
joelostblom

Reputation: 49044

Another way of solving this is to first stash any uncommitted changes using git stash and then run

git pull --rebase=interactive -s recursive -X theirs

In the interactive rebase you can change all your local undesired commits to drop, which will get rid of them and leave you at the head of the remote branch without introducing a merge commit.

Now you can run git stash apply if you had local stashed changed that you want to bring back.

Upvotes: 5

Ultan Kearns
Ultan Kearns

Reputation: 115

You could try git pull --force or maybe stash your commits by using git stash and then running git pull.

Upvotes: -4

Richard
Richard

Reputation: 5880

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.

Upvotes: 504

Step 1. (optional)
From the root of your local repository, save a backup and empty the current folder:

mkdir -p ../<branch>-bkp && mv --backup=t * ../<branch>-bkp

Step 2. Download all files and folders of the branch from the remote repository:

git checkout <branch> && git add -A . && git reset --hard origin/<branch> && git pull

where you should replace <branch> with the name of the branch you want to overwrite.

Comments:

  • You may prefer to manually backup and remove the current files and folders instead of step 1.
    In fact, I recommend doing this with a file-handler in the GUI of your operating system.
  • If you skip step 1, beware: you will lose all work in the local repository!
  • Important: if you leave out git pull in step 2,
    you risk not getting the latest version from the remote repository!
    According to the second reference below, git reset --hard will
    reset the staging area and the working directory to match the most recent commit.
    My experience contradicts this claim!
  • If you run git reset --hard origin/<branch_to_overwrite> without first deleting all files and folders from your local repository, beware that any junk files still laying around may sneak into the remote repository at a later git push even if that was not your intention.
    The extra git add -A . in step 2 prevents this from happening if you choose to leave out step 1.

References:
https://gitforwindows.org/
https://www.atlassian.com/git/tutorials/undoing-changes/git-reset
https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog

Upvotes: 0

guillem
guillem

Reputation: 2998

Despite the fact that this question has already many answers, the original question is to solve this question

error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge

As binary files can't be merged a simple answer is

git checkout public/images/icon.gif

With that the file will recover the previous state it had in this branch.

I usually do git stash if I don't want to lose my changes or something like git checkout . if I don't care about locally modified files. IMO much more simple than reset --hard, clean... and all this stuff more suited to leave the branch as in remote, including commits, untracked files, rather than just solving a locally modified file.

Upvotes: 3

Ashutosh Nigam
Ashutosh Nigam

Reputation: 876

Once you do git pull, you will get list of files that are not matching. If the number of files is not very large then you can checkout those files, this action will overwrite those files.

git checkout -- <filename>

I usually do it if for quick check I modify local files on server (no recommended and probabaly reason behind you getting this issue :D ), I checkout the changed files after finding solution.

Upvotes: 2

kenorb
kenorb

Reputation: 166795

First of all, try the standard way:

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!

Warning: Above commands can results in data/files loss only if you don't have them committed! If you're not sure, make the backup first of your whole repository folder.

Then pull it again.

If above won't help and you don't care about your untracked files/directories (make the backup first just in case), try the following simple steps:

cd your_git_repo  # where 'your_git_repo' is your git repository folder
rm -rfv *         # WARNING: only run inside your git repository!
git pull          # pull the sources again

This will REMOVE all git files (excempt .git/ dir, where you have all commits) and pull it again.


Why git reset HEAD --hard could fail in some cases?

  1. Custom rules in .gitattributes file

    Having eol=lf rule in .gitattributes could cause git to modify some file changes by converting CRLF line-endings into LF in some text files.

    If that's the case, you've to commit these CRLF/LF changes (by reviewing them in git status), or try: git config core.autcrlf false to temporary ignore them.

  2. File system incompability

    When you're using file-system which doesn't support permission attributes. In example you have two repositories, one on Linux/Mac (ext3/hfs+) and another one on FAT32/NTFS based file-system.

    As you notice, there are two different kind of file systems, so the one which doesn't support Unix permissions basically can't reset file permissions on system which doesn't support that kind of permissions, so no matter how --hard you try, git always detect some "changes".

Upvotes: 70

John John
John John

Reputation: 4575

I had the same problem. No one gave me this solution, but it worked for me.

I solved it by:

  1. Delete all the files. Leave just the .git directory.
  2. git reset --hard HEAD
  3. git pull
  4. git push

Now it works.

Upvotes: 60

abhijithvijayan
abhijithvijayan

Reputation: 931

1: Reset to a previous commit

git reset --hard HEAD

2: Delete Untracked Files

git clean -f

3: Pull the commits

git pull

Sources:

Upvotes: 5

ddmytrenko
ddmytrenko

Reputation: 824

I know of a much easier and less painful method:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

That's it!

Upvotes: 22

David Avsajanishvili
David Avsajanishvili

Reputation: 8036

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
...

Upvotes: 613

Sazzad Hissain Khan
Sazzad Hissain Khan

Reputation: 40237

Bonus:

In speaking of pull/fetch/merge in the previous answers, I would like to share an interesting and productive trick,

git pull --rebase

This above command is the most useful command in my Git life which saved a lot of time.

Before pushing your newly commit to server, try this command and it will automatically synchronise the latest server changes (with a fetch + merge) and will place your commit at the top in the Git log. There isn't any need to worry about manual pull/merge.

Find details in What does "git pull --rebase" do?.

Upvotes: 65

Luca C.
Luca C.

Reputation: 12594

On Windows, do this single command:

git fetch --all & git reset --hard origin/master

Upvotes: 7

Lloyd Moore
Lloyd Moore

Reputation: 3197

Instead of merging with git pull, try this:

git fetch --all

followed by:

git reset --hard origin/master.

Upvotes: 109

Related Questions