Re: [PATCH] git stash: Avoid data loss when saving a stash
From: Petr Baudis <hidden>
Date: 2016-06-15 22:58:01
Hi! (tl;dr - I disagree but this issue is perhaps not so important in practice) On Sun, Jun 30, 2013 at 12:14:26PM -0700, Junio C Hamano wrote:
I do not agree with your `git reset --hard` at all. With the command, the user demands "no matter what, I want get rid of any funny state in my working tree so that I can start my work from that specified commit (default to HEAD)".
Yeah, but this normally concerns only tracked files; `git reset --hard` does not imply `git clean`. I'm worried when a tool normally behaves in a way that follows an apparent rule but its behavior is defined in such a way that in a corner case this rule is violated (but it's ok since it's a - non-obvious - implication of the specification).
Imagine that this is you did to arrive that "funny state":
$ git rm foo ;# foo used to be tracked and in HEAD
$ cp /somewhere/else/foo foo
$ cp /somewhere/else/bar bar ;# bar is not in HEAD
$ cp /somewhere/else/bar baz ;# baz is in HEAD
... do various other things ...
and then "git reset --hard". At that point, "foo" and "bar" are not
tracked and completely unrelated to the project. "baz" is tracked
and have unrelated contents from that of "HEAD".
In order to satisfy your desire to go back to the state of HEAD with
minimal collateral amage, we need to get rid of the updated "foo"
and "baz" and replace them with those from HEAD. We do not have to
touch "bar" so we leave it as-is.Perhaps we misundertood each other here. I certainly don't care to keep local changes as a whole - a command behaving like that wouldn't be very useful for me; for me, the crucial distinction is between tracked and untracked files. Therefore, from my viewpoint it's fine to overwrite baz, but not to overwrite foo.
And the "killed" case is just like "foo" and "baz". If the state you want to go back to with "--hard" has a directory (a file) where your working tree's funny state has a file (a directory), the local cruft needs to go away to satisify your request. I do not mind if you are proposing a different and new kind of reset that fails if it has to overwrite any local changes (be it tracked or untracked), but that is not "reset --hard". It is something else.
Hmm, I suppose the assumption I would prefer is that "the only command that will destroy (currently) untracked data without warning is `git clean`"; even though (unlike in case of git stash) the current reset --hard behavior wouldn't surprise me, I suspect it can be a bad surprise for many Git users when they hit this situation; but since I didn't notice any actual complaint yet, so I don't care enough to press this further for now anyway. :-) -- Petr "Pasky" Baudis For every complex problem there is an answer that is clear, simple, and wrong. -- H. L. Mencken