Can you get access to files git stashes if git stash pop refuses to merge?

45 views Asked by At

How do I get access to data git stash refuses to merge

I ran

git stash      # two files not stashed since they were not in git yet
git stash -u   # add the sfiles to the stash
git pull
git stash pop

Git refuses to un-stash because the pull has two files that were added with (-u untracked files)

error: could not restore untracked files from stash 
The stash entry is kept in case you need it again. 

git stash show 0

shows nothing. Is there a way to get at the files given stash wont pop? Is there a patch file in .git somewhere?

1

There are 1 answers

2
larsks On

A stash is just a commit, so you can use regular tools like git show to access files in the stash. Let's say I have one unstaged change and one untracked file:

$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   README.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        example.txt

If I run git stash -u, I end up with a commit object named refs/stash:

$ git for-each-ref
54884038278578c80ed2aae843c74a38aafcebb7 commit refs/heads/main
879c8e21be397501fd4d9fd1440bff8fa79cc431 commit refs/stash

Unstaged changes (that is, changes to files that are tracked by git) are stored directly in refs/stash:

$ git show refs/stash
commit 879c8e21be397501fd4d9fd1440bff8fa79cc431
Merge: 5488403 cb7969c b3c4ebe
Author: Alice Example <[email protected]>
Date:   Fri Feb 16 07:05:04 2024 -0500

    WIP on main: 5488403 Initial commit

diff --cc README.md
index b4f9938,b4f9938,0000000..b75fee6
mode 100644,100644,000000..100644
--- a/README.md
+++ b/README.md
@@@@ -1,1 -1,1 -1,0 +1,2 @@@@
  +This is an example of working with `git stash`.
+++This is an unstaged change

I can extract an individual file like this:

$ git show refs/stash:README.md
This is an example of working with `git stash`.
This is an unstaged change

Untracked files are stored in refs/stash^3:

$ git show refs/stash^3
commit b3c4ebed5f3566f37697c9adad2f15159a25c731
Author: Alice Example <[email protected]>
Date:   Fri Feb 16 07:05:04 2024 -0500

    untracked files on main: 5488403 Initial commit

diff --git a/example.txt b/example.txt
new file mode 100644
index 0000000..79d897a
--- /dev/null
+++ b/example.txt
@@ -0,0 +1 @@
+This is an untracked file

And I can extract files in a similar fashion:

$ git show refs/stash^3:example.txt
This is an untracked file

We can also check out the stash as a new branch. Using git worktree allows us to put this in a new directory. The following creates a new branch named unstaged-changes with the contents of refs/stash^3 and checks it out into the ../unstaged-changes directory:

$ git worktree add -b unstaged-changes ../unstaged-changes refs/stash^3
Preparing worktree (new branch 'unstaged-changes')
HEAD is now at b3c4ebe untracked files on main: 5488403 Initial commit
$ ls ../unstaged-changes/
example.txt