threads / bug / 64198

Bug report: Untracked file lost from git stash

Subject: Bug report: Untracked file lost from git stash

## tl;dr

4 messages between Sep 24, 2025 and Sep 25, 2025.

replies: 3people: 3as markdown or json

Hosam Aly· Sep 24, 2025, 15:29 UTC · lore
Hello,

Thank you for filling out a Git bug report! Please answer the following questions to help us understand your issue.

What did you do before the bug happened? (Steps to reproduce your issue) I have a file in one directory. I made many changes _and_ moved it to a different directory, but that caused git to lose track of the renaming due to a low similarity index. As such, I decided to do it in two steps and used `git stash -u` to shelve my changes. Following that, I moved the file and then tried to unstash it, assuming that the worst that could happen would be a conflict that I would easily solve. ``` git init . mkdir d1 d2 echo code1 > d1/f git add d1/f git commit -m 'Add file in d1' mv d1/f d2/ echo code2 > d2/f git stash -u git stash show --stat

git mv d1/f d2/ git commit -m 'Move file to d2' echo code3 > d2/f git stash pop ```

What did you expect to happen? (Expected behavior)
* `git stash show` should show a file that was deleted and another
that is untracked and has different contents.
* `git stash pop` should apply the changes, potentially with the
conflict markers.
What happened instead? (Actual behavior)
* The stash shows the deleted file but not the untracked one!
  ```
   d1/f | 1 -
   1 file changed, 1 deletion(-)
  ```
* `git stash pop` says it's unable to restore the untracked file.
What's different between what you expected and what actually happened?
* The stash entry doesn't show the untracked file. It should show it
(or refuse to create the stash).
* Trying `git checkout 'stash@{0}' -- d2/f` says it doesn't know about the file.

Anything else you want to add: I seem to have lost the changes I made (symbolized by code2 above). I wasn't able to restore them using any of the git commands that I know. I'm no expert but I'm the best in my company at using Git, and yet I wasn't able to restore code2 using any git commands.

Please review the rest of the bug report below. You can delete any lines you don't wish to share.

[System Info]
git version:
git version 2.51.0
cpu: arm64
no commit associated with this build
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
feature: fsmonitor--daemon
libcurl: 8.7.1
zlib: 1.2.12
SHA-1: SHA1_DC
SHA-256: SHA256_BLK
default-ref-format: files
default-hash: sha1
uname: Darwin 24.6.0 Darwin Kernel Version 24.6.0: Mon Aug 11 21:15:09
PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6041 arm64
compiler info: clang: 17.0.0 (clang-1700.0.13.3)
libc info: no libc information available
$SHELL (typically, interactive shell): /bin/zsh
[Enabled Hooks]
D. Ben Knoble· Sep 24, 2025, 18:13 UTC · re: Hosam Aly · lore

Re: Bug report: Untracked file lost from git stash

On Wed, Sep 24, 2025 at 11:33 AM Hosam Aly <hosamaly6@gmail.com> wrote:
Show 13 quoted lines
>
> Hello,
>
> Thank you for filling out a Git bug report!
> Please answer the following questions to help us understand your issue.
>
> What did you do before the bug happened? (Steps to reproduce your issue)
> I have a file in one directory. I made many changes _and_ moved it to
> a different directory, but that caused git to lose track of the
> renaming due to a low similarity index. As such, I decided to do it in
> two steps and used `git stash -u` to shelve my changes. Following
> that, I moved the file and then tried to unstash it, assuming that the
> worst that could happen would be a conflict that I would easily solve.

I touch on a few helpful pieces below, but one thing I can't puzzle out: what is the "echo code3 >d2/f" representing below in the story above? (I don't think it ends up mattering for the case of the stash conflict though.)

Show 9 quoted lines
> git init .
> mkdir d1 d2
> echo code1 > d1/f
> git add d1/f
> git commit -m 'Add file in d1'
> mv d1/f d2/
> echo code2 > d2/f
> git stash -u
> git stash show --stat
At this stage, "git stash show" is not very helpful:
show [-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>]
           Show the changes recorded in the stash entry as a diff between the
           stashed contents and the commit back when the stash entry was first
           created.
(At least, not without "-u"):
    # git stash show -u
     d1/f | 1 -
     d2/f | 1 +
     2 files changed, 1 insertion(+), 1 deletion(-)

On the other hand, we can do "git log --oneline --graph stash" to see that stash^3 contains a new root commit with the untracked files.

So
> git mv d1/f d2/
> git commit -m 'Move file to d2'
> echo code3 > d2/f
> git stash pop
here, "git restore -SW -s stash^3 d2/f" might be what you want?
For the record, the error message I get is
CONFLICT (rename/delete): d1/f renamed to d2/f in Updated upstream,
but deleted in Stashed changes.
d2/f already exists, no checkout
error: could not restore untracked files from stash
On branch main
Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add/rm <file>..." as appropriate to mark resolution)
deleted by them: d2/f

no changes added to commit (use "git add" and/or "git commit -a") Your stash currently has 1 entry The stash entry is kept in case you need it again.

And then
    # g ls-files --stage
    100644 47f43aef120505c79eafd2b1bd55e4cb78977f98 1 d2/f
    100644 47f43aef120505c79eafd2b1bd55e4cb78977f98 2 d2/f

That is the code1 blob. The working tree still has code3. It _would_ be nice to perhaps see a conflict with the code2 blob?

Show 19 quoted lines
>
> What did you expect to happen? (Expected behavior)
> * `git stash show` should show a file that was deleted and another
> that is untracked and has different contents.
> * `git stash pop` should apply the changes, potentially with the
> conflict markers.
>
> What happened instead? (Actual behavior)
> * The stash shows the deleted file but not the untracked one!
>   ```
>    d1/f | 1 -
>    1 file changed, 1 deletion(-)
>   ```
> * `git stash pop` says it's unable to restore the untracked file.
>
> What's different between what you expected and what actually happened?
> * The stash entry doesn't show the untracked file. It should show it
> (or refuse to create the stash).
> * Trying `git checkout 'stash@{0}' -- d2/f` says it doesn't know about the file.

The merge result in stash^{tree} doesn't have the untracked file, but it does exist in stash^3 as explained above.

Yet another way to recover is "git stash branch <branch>", which should never fail from a clean working tree.

-- 
D. Ben Knoble
Hosam Aly· Sep 25, 2025, 20:22 UTC · re: D. Ben Knoble · lore

Re: Bug report: Untracked file lost from git stash

One learns everyday, and today is definitely a good one. Thanks a lot! It was a red herring but I do have a feature suggestion at the end of this message.

I had found `git stash show` easy to use that I never thought about reading its docs. I apologise for the false alarm.

I was surprised to learn that `git stash` has an option to show untracked files. I find this unintuitive because it's the opposite of the default behaviour of `git status`! I'll configure `stash.showIncludeUntracked` to get them to behave similarly. Thanks very much for pointing it out.

I learned today how `git stash branch` can be a lifesaver. Much appreciated!

As for "echo code3 >d2/f", I had written it in an incorrect order. It should've been after the move and before the commit. The actual scenario was that I was working with a Java file that I moved to a different package, which involved changing the package declaration at the top of the file.

Feature request: I wish that the maintainers would consider changing the default value of `stash.showIncludeUntracked` to true. If something is stashed and the user asks about it, they should be told about it without hiding anything. Consider the case where all the stashed files are untracked; `git stash show` currently shows nothing, which is very confusing.

Thank you very much, Hosam Aly

On Wed, 24 Sept 2025 at 21:13, D. Ben Knoble <ben.knoble@gmail.com> wrote:
Show 110 quoted lines
>
> On Wed, Sep 24, 2025 at 11:33 AM Hosam Aly <hosamaly6@gmail.com> wrote:
> >
> > Hello,
> >
> > Thank you for filling out a Git bug report!
> > Please answer the following questions to help us understand your issue.
> >
> > What did you do before the bug happened? (Steps to reproduce your issue)
> > I have a file in one directory. I made many changes _and_ moved it to
> > a different directory, but that caused git to lose track of the
> > renaming due to a low similarity index. As such, I decided to do it in
> > two steps and used `git stash -u` to shelve my changes. Following
> > that, I moved the file and then tried to unstash it, assuming that the
> > worst that could happen would be a conflict that I would easily solve.
>
> I touch on a few helpful pieces below, but one thing I can't puzzle
> out: what is the "echo code3 >d2/f" representing below in the story
> above? (I don't think it ends up mattering for the case of the stash
> conflict though.)
>
> > git init .
> > mkdir d1 d2
> > echo code1 > d1/f
> > git add d1/f
> > git commit -m 'Add file in d1'
> > mv d1/f d2/
> > echo code2 > d2/f
> > git stash -u
> > git stash show --stat
>
> At this stage, "git stash show" is not very helpful:
>
> show [-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>]
>            Show the changes recorded in the stash entry as a diff between the
>            stashed contents and the commit back when the stash entry was first
>            created.
>
> (At least, not without "-u"):
>
>     # git stash show -u
>      d1/f | 1 -
>      d2/f | 1 +
>      2 files changed, 1 insertion(+), 1 deletion(-)
>
> On the other hand, we can do "git log --oneline --graph stash" to see
> that stash^3 contains a new root commit with the untracked files.
>
> So
>
> > git mv d1/f d2/
> > git commit -m 'Move file to d2'
> > echo code3 > d2/f
> > git stash pop
>
> here, "git restore -SW -s stash^3 d2/f" might be what you want?
>
> For the record, the error message I get is
>
> CONFLICT (rename/delete): d1/f renamed to d2/f in Updated upstream,
> but deleted in Stashed changes.
> d2/f already exists, no checkout
> error: could not restore untracked files from stash
> On branch main
> Unmerged paths:
>   (use "git restore --staged <file>..." to unstage)
>   (use "git add/rm <file>..." as appropriate to mark resolution)
> deleted by them: d2/f
>
> no changes added to commit (use "git add" and/or "git commit -a")
> Your stash currently has 1 entry
> The stash entry is kept in case you need it again.
>
> And then
>
>     # g ls-files --stage
>     100644 47f43aef120505c79eafd2b1bd55e4cb78977f98 1 d2/f
>     100644 47f43aef120505c79eafd2b1bd55e4cb78977f98 2 d2/f
>
> That is the code1 blob. The working tree still has code3. It _would_
> be nice to perhaps see a conflict with the code2 blob?
>
> >
> > What did you expect to happen? (Expected behavior)
> > * `git stash show` should show a file that was deleted and another
> > that is untracked and has different contents.
> > * `git stash pop` should apply the changes, potentially with the
> > conflict markers.
> >
> > What happened instead? (Actual behavior)
> > * The stash shows the deleted file but not the untracked one!
> >   ```
> >    d1/f | 1 -
> >    1 file changed, 1 deletion(-)
> >   ```
> > * `git stash pop` says it's unable to restore the untracked file.
> >
> > What's different between what you expected and what actually happened?
> > * The stash entry doesn't show the untracked file. It should show it
> > (or refuse to create the stash).
> > * Trying `git checkout 'stash@{0}' -- d2/f` says it doesn't know about the file.
>
> The merge result in stash^{tree} doesn't have the untracked file, but
> it does exist in stash^3 as explained above.
>
> Yet another way to recover is "git stash branch <branch>", which
> should never fail from a clean working tree.
>
> --
> D. Ben Knoble
Junio C Hamano· Sep 25, 2025, 21:06 UTC · re: Hosam Aly · lore

Re: Bug report: Untracked file lost from git stash

Hosam Aly <hosamaly6@gmail.com> writes:
Show 6 quoted lines
> Feature request: I wish that the maintainers would consider changing
> the default value of `stash.showIncludeUntracked` to true. If
> something is stashed and the user asks about it, they should be told
> about it without hiding anything. Consider the case where all the
> stashed files are untracked; `git stash show` currently shows nothing,
> which is very confusing.

Do we include untracked paths in the stash by default without configuration and/or command line option? If we do, then such a change will affect so many folks that it would be possible to do so only at a large version boundary, like Git 3.0.

But untracked paths are not recorded by default, and a stash entry that records the untracked ones is a sign enough that the user cares about these untracked ones when the stash entry was created.

Even though I do dislike any suggestion to change existing behaviour established more than a few years, I would be more sympathetic than usual to a wish for such a change in the default. In other words, I tend to agree that the default should show untracked if recorded. I am actually tempted to argue that the presence of the configuration variable stash.showIncludeUntracked and the "--include-untracked" command line option is a bug ;-) but I won't.

Thanks.

← back to recent threads