git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: git stash data loss

From
APAleksandr Priymak <tramsmm-mirror@yandex.ru>
Date
Jul 27, 2012, 14:21 UTC
Message-ID
<6BE6FF9E-0952-45D8-AFA7-0843CE3CFC5A@yandex.ru>
In-Reply-To
<20120727132953.GA8263@sigill.intra.peff.net>
Thanks Jeff for the comment. You are right. I oversimplified the use-case ( forget to fill the directory )
Sent from my iPad
On Jul 27, 2012, at 5:29 PM, Jeff King <peff@peff.net> wrote:
Show 85 quoted lines
> On Fri, Jul 27, 2012 at 07:06:08AM +0400, Aleksandr Pryimak wrote:
> 
>> I also recreated it
>> 
>> aleksandr@beast:/tmp/test$ git init
>> Initialized empty Git repository in /tmp/test/.git/
>> aleksandr@beast:/tmp/test$ touch x
>> aleksandr@beast:/tmp/test$ git add x
>> aleksandr@beast:/tmp/test$ git commit -m "Initial"
>> [master (root-commit) d3569a0] Initial
>> 0 files changed, 0 insertions(+), 0 deletions(-)
>> create mode 100644 x
> 
> OK, so we have "x" as a tracked file.
> 
>> aleksandr@beast:/tmp/test$ rm x
>> aleksandr@beast:/tmp/test$ mkdir x/
>> aleksandr@beast:/tmp/test$ ls
>> x
> 
> And then we remove it in favor of a directory. Note that git does not
> track directories directly, only files inside them. So from git's
> perspective, the working tree has no content in it at all.
> 
>> aleksandr@beast:/tmp/test$ git stash
>> Saved working directory and index state WIP on master: d3569a0 Initial
>> HEAD is now at d3569a0 Initial
> 
> And now we stash it. That will stash the working tree removal of x. It
> will not stash anything about the new directory x, because it has no
> content inside it.
> 
>> aleksandr@beast:/tmp/test$ ls
>> x
>> aleksandr@beast:/tmp/test$ git stash pop
>> Removing x
>> # On branch master
>> # Changes not staged for commit:
>> #   (use "git add/rm <file>..." to update what will be committed)
>> #   (use "git checkout -- <file>..." to discard changes in working directory)
>> #
>> #    deleted:    x
>> #
>> no changes added to commit (use "git add" and/or "git commit -a")
>> Dropped refs/stash@{0} (c500443ae16cf0d846b195cb97eb388dec5f440e)
>> aleksandr@beast:/tmp/test$ ls
> 
> And your stash pop restores the deletion of "x". It does _not_ reinstate
> the directory "x", because as I stated above, that is not part of the
> stash.
> 
> So what is the data loss? That the "mkdir x" was lost? That has nothing
> to do with stash, but rather the fact that git does not track empty
> directories. You could see the same thing with:
> 
>  mkdir x && git commit -a
> 
> which will not record your mkdir at all. In other words, this is by
> design.
> 
> If we put actual files inside "x", which git does track, then they would
> be part of the stash, and should be properly retained. But they're not:
> 
>  $ rm x && mkdir x && echo foo >x/file
> 
> Now we have some precious contents in the form of "x/file". They are
> untracked by git, but git should be careful about removing them.
> 
>  $ git stash
>  Saved working directory and index state WIP on master: 2d32d3a initial
>  HEAD is now at 2d32d3a initial
>  $ ls -l x
>  -rw-r--r-- 1 peff peff 0 Jul 27 09:19 x
>  $ git stash show --raw
>  :100644 000000 e69de29... 0000000... D  x
> 
> Now this _is_ data loss. Stash blows away untracked files inside the
> directory, but does not record them in the resulting stash. And that
> should be fixed.
> 
> With "-u", I'd expect stash to include the untracked file x/foo in the
> stash. Without "-u", I'd expect stash to fail, since it would be
> deleting untracked files.
> 
> -Peff
Previous: Junio C Hamano
Message 7 of 7 in “git stash data loss”
  1. Aleksandr PryimakJul 27, 2012
  2. Jeff KingJul 27, 2012
  3. Jeff KingJul 27, 2012
  4. Junio C HamanoAug 17, 2012
  5. Jeff KingAug 21, 2012
  6. Junio C HamanoSep 14, 2012
  7. Aleksandr PriymakJul 27, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.