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

Re: Git reset --hard with staged changes

From
Christian Couder <christian.couder@gmail.com>
Date
May 23, 2016, 19:31 UTC
Message-ID
<CAP8UFD0dQGmfhPuHjEGRZjEZHwUHR_XzAASwq+87Obf26yi+BQ@mail.gmail.com>
In-Reply-To
<loom.20160523T023140-975@post.gmane.org>
On Mon, May 23, 2016 at 2:55 AM, Yotam Gingold <yotam@yotamgingold.com> wrote:
Show 44 quoted lines
> Pierre-François CLEMENT <likeyn <at> gmail.com> writes:
>> 2014-06-10 17:27 GMT+02:00 David Kastrup <dak <at> gnu.org>:
>>> Pierre-François CLEMENT <likeyn <at> gmail.com> writes:
>>>
>>>> ...
>>>>
>>>> Hm I see. Even though the documentation doesn't make it very clear
>>>> about what happens to such files, it turns out the scenario we
>>>> stumbled upon seems to be the special use case after all. Thanks for
>>>> shedding some light on this :) I wonder why does git-reset's hard mode
>>>> not always remove untracked files then?
>>>
>>> Because it never removes them?  Git only removes files once it tracks
>>> them.  This includes the operation of removing _and_ untracking them,
>>> like with git reset --hard.
>>>
>>> The only command which explicitly messes with untracked files is
>>> git-clean.
>>>
>>> --
>>> David Kastrup
>>
>> ... I couldn't find a definition that backs this in the man
>> pages (maybe the git-glossary would be a good place for it?), and the
>> one from the Git-Scm book only confused me in thinking the opposite.
>> Thanks for the clarification
>>
>> --
>> Pierre-François CLEMENT
>> Application developer at Upcast Social
>
> Jumping into this conversation two years later*. There's confusion about what
> constitutes a tracked file for git reset --hard, and good reasons for git reset
> --hard's behavior. Nevertheless, I think we can all agree that the man page
> entry for git reset --hard is woefully deficient:
>
> --hard Resets the index and working tree. Any changes to tracked files in the
> working tree since <commit> are discarded.
>
> This should be clarified to define what a tracked file is. I propose appending:
>
>     A file is considered tracked if it exists in a prior commit or in the
>     staging area. Note that a newly added file not in any prior commit will be
>     removed.
Would you like to send a patch with something like the above?

I don't know if something about why it is like this, or why it is the right thing to do, at least for recovering from merges, should be added though.

Show 15 quoted lines
> I would also like to propose that the staging area's tree object be saved,
> perhaps in the reflog or perhaps just as a dangling object. This would allow
> graceful recovery from git reset --hard. Witness the many questions and answers
> on recovery:
>     http://stackoverflow.com/questions/7374069/undo-git-reset-hard-with-uncommitted-files-in-the-
> staging-area
>     http://stackoverflow.com/questions/5788037/recover-from-git-reset-hard
>     http://stackoverflow.com/questions/5473/how-can-i-undo-git-reset-hard-head1
>     http://gitready.com/advanced/2009/01/17/restoring-lost-commits.html
>     https://bani.com.br/2014/10/recovering-lost-files-after-a-git-reset-hard/
>     https://medium.com/@CarrieGuss/how-to-recover-from-a-git-hard-reset-b830b5e3f60c
>
> All of these solutions recover the contents of files, but not their names or the
> directory structure. Saving the tree object somewhere (anywhere!) would solve
> this problem.
Yeah, it might be a good idea.
> I was bitten by this in a vicious way. I was setting up a new repository for a
> bunch of code and data (git init; git add .), changed my mind about adding the
> data (git reset --hard), and nearly lost everything.

I think we could also perhaps have a special case when the current branch doesn't really exist yet.

At least if you had used "git reset --keep", it would have failed with:

$ git reset --keep error: You do not have a valid HEAD. fatal: Could not reset index file to revision 'HEAD'.

Also if there had already been a commit, with --keep the new files would not have been deleted.

> The only tree object that
> could be found was an empty one, so I got file contents without names or
> directories (not good, because experimental conditions for the data were encoded
> in the directory structure).

Best, Christian.

Previous: Junio C HamanoNext: Junio C Hamano
Message 3 of 8 in “Re: Git reset --hard with staged changes”
  1. Yotam GingoldMay 23, 2016
  2. Junio C HamanoMay 23, 2016
  3. Christian CouderMay 23, 2016
  4. Junio C HamanoMay 23, 2016
  5. Christian CouderMay 24, 2016
  6. Yotam GingoldMay 30, 2016
  7. Junio C HamanoMay 31, 2016
  8. Christian CouderMay 31, 2016

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.