352

I have some files which were untracked in git. I made some changes and wanted to commit them, but realised I had forgotten to check in the unmodified files first. So I stashed the files, then added the unmodified versions.

Then when I apply the stash to the repository, I get conflicts due to the files having already been added.

How can I apply the stash, and force the versions in the stash to be used in preference to the originals in the repository?

Thanks

Stefan
  • 8,819
  • 10
  • 42
  • 68
  • 13
    Ugly solution until somebody comes up with a better one: remove the new files using `git rm` before doing `git stash apply`. – tom May 17 '13 at 10:08
  • Won't that lose the history? The reason for adding the unmodified versions was to keep the history. – Stefan May 17 '13 at 10:11
  • 1
    No, it will not lose the history. If you remove a file, add it back with a small modification, and then commit, `git` will treat it as just a small modification. – tom May 17 '13 at 10:19

9 Answers9

569

Use git checkout instead of git stash apply.

WARNING: The command below will restore all the files in the current directory (.) to their stashed version. If you have uncommitted or unstaged changes, they will be permanently lost:

  • If you edited files after creating the stash, those changes will be lost.
  • If you only stashed specific files (using git stash push <pathspec>... or git stash -p), do not use this command because changes in all other files will be lost.

Use git status to check that there are no uncommitted or unstaged changes before running this command.

# WARNING: uncommitted/unstaged changes will be permanently lost
$ git checkout stash -- .
$ git commit

If there are changes to other files in the working directory that should be kept, here is a less heavy-handed alternative:

$ git merge --squash --strategy-option=theirs stash

If there are changes in the index, or the merge will touch files with local changes, git will refuse to merge. Individual files can be checked out from the stash using

$ git checkout stash -- <paths...>

or interactively with

$ git checkout -p stash
tom
  • 21,844
  • 6
  • 43
  • 36
  • None of these worked in my use case. Findings and my solution are here http://stackoverflow.com/a/26685296/496046 -- this should solve your situation too, @AlexanderBird – tremby Nov 01 '14 at 01:50
  • 4
    `git checkout stash -- .` This command literally did nothing when I ran it. – Rotsiser Mho Dec 22 '15 at 04:31
  • 3
    @RotsiserMho Git is not very good about providing confirmation messages. Are you sure it did nothing? Worked fine for me. – Sinjai Aug 21 '17 at 18:48
  • 7
    I had to run `git checkout stash -- .` in the highest parent folder that contained my changes, otherwise it only applied changes to the folder from where I ran the command. – Leo Feb 28 '18 at 09:27
  • 1
    @Leo: That's right, it's because `.` specifies the current directory (you could replace it with a different path instead of changing directory). I updated my answer to make that clearer. – tom Mar 01 '18 at 07:31
  • This was helpful but it didn't restore *untracked* files - if you have the same problem (`already exists, no checkout`), check my solution [here](https://stackoverflow.com/a/55799386/4080966). – Erik Koopmans Apr 22 '19 at 18:43
  • For individual files, would `git checkout stash -- $FILE` be equivalent to `git show stash:$FILE > $FILE`? – Agilix May 27 '20 at 12:55
  • @Agilix Yes (but only the first one sets the file mode). – tom May 28 '20 at 13:18
  • 1
    @tom Semi-hard way. I did overwrite unstaged changes, but luckily there was another recovery option: PHPStorm's local history saved my sorry ass. – Szczepan Hołyszewski May 23 '22 at 10:04
  • 1
    Why would you use a method other than the `git merge` one? In what cases would it do the wrong thing? Seems like it's less error prone. – idbrii May 09 '23 at 18:29
  • 1
    @idbrii: You'd use checkout if you wanted to make your worktree exactly\* like the stash. The merge approach will keep any non-conflicting changes, which may or may not be desirable. You can use `git diff stash` to review the changes and decide. (\*checkout won't delete new files) – tom May 11 '23 at 07:19
42

git stash show -p | git apply

and then git stash drop if you want to drop the stashed items.

Hassan TBT
  • 805
  • 7
  • 5
  • 2
    Note: you should be in the root of the repository for this to work correctly, otherwise you'll get [this](https://stackoverflow.com/a/45496547/673852). – Ruslan Sep 10 '18 at 06:35
  • @Ruslan I'm getting that while in the root of my repo – Leo Jan 09 '20 at 17:21
  • 1
    and what to do if I get "patch does not apply"? I just would like to get my stashed changes! – eis Apr 07 '22 at 09:09
  • 2
    @eis you can add `--reject --whitespace=fix` as options for `git apply`. Check [this explanation](https://stackoverflow.com/a/15375869/5493628) for how it works. All together: `git stash show -p | git apply --reject --whitespace=fix` – Hassan TBT Apr 12 '22 at 03:19
  • @HassanTBT Bizarrely, this completely ignored one of the files with stashed changes for me. It also left me with some .rej files to clean up. I had to resort to this: https://stackoverflow.com/a/76680580/1715765 – H.v.M. Jul 13 '23 at 14:36
  • @HassanTBT with that, I get "error: patch failed" – eis Jul 18 '23 at 10:57
18

To force git stash pop run this command

git stash show -p | git apply && git stash drop
Emmac
  • 2,928
  • 2
  • 15
  • 22
4

TL;DR:

git checkout HEAD path/to/file
git stash apply

Long version:

You get this error because of the uncommited changes that you want to overwrite. Undo these changes with git checkout HEAD. You can undo changes to a specific file with git checkout HEAD path/to/file. After removing the cause of the conflict, you can apply as usual.

User12547645
  • 6,955
  • 3
  • 38
  • 69
  • 1
    "You get this error because of the uncommited changes that you want to overwrite." This is not necessarily true. If the stash is originally from a different branch and both your current branch and the stashed changes modify the same files, you will get a merge conflict as well. – tjalling Oct 16 '20 at 12:37
  • Thumbs up for the idea to revert your changes to solve the issue. This is especially useful when changes' reversion is manageable. – vpap May 17 '23 at 12:00
2

Keep local source backup then apply force reset to align with GIT repo. Then change your local code and commit.

git reset --hard FETCH_HEAD

Mahbub Tito
  • 1,057
  • 8
  • 7
0

In my case git checkout stash -- would throw this error

error: Your local changes to the following files would be overwritten by checkout:
... files ...
Please commit your changes or stash them before you switch branches.
Aborting

The solution was to do git checkout stash -- /path/to/each/individual/file.

vpap
  • 1,389
  • 2
  • 21
  • 32
0

I think this option from tom's answer is the simplest and least error-prone method of autoresolving conflicts when applying a stash:

$ git merge --squash --strategy-option=theirs stash

You can input it exactly like that: git uses stash as a commitish to refer to the top of the stash.

It will leave you with all the stashed files added to the index and resolved to match the stash, but doesn't create any commits. Additionally, it will abort if you have local changes in your working copy you don't risk losing changes.

It's so useful, that I think it's worth an alias in ~/.gitconfig:

[alias]
    stashforceapply = "!f() { stash=${1:-stash}; git merge --squash --strategy-option=theirs $stash ; }; f"

Use git stashforceapply for the top stash, or git stashforceapply stash@{1} for the next, etc.

idbrii
  • 10,975
  • 5
  • 66
  • 107
0

WARNING This will delete all uncommited changes

git checkout HEAD --force
git stash apply
deanqx
  • 75
  • 1
  • 7
0

The other solutions didn't work for me. Here's what I did:

git branch temp && git reset --hard stash && git reset temp && git branch -D temp

To hard-reset and then reset back changes your working tree without changing your branch.

H.v.M.
  • 1,348
  • 3
  • 16
  • 42