# Re: Git reset --hard with staged changes

9 messages from 2014-06-09 to 2014-06-10. Participants: Pierre-François CLEMENT, David Kastrup, Junio C Hamano, Dale Worley.
Thread: https://gitlist.dev/t/36872

## Pierre-François CLEMENT, 2014-06-09 11:24

Subject: Re: Git reset --hard with staged changes
Message-ID: <CANWD=rX-MEiS4cNzDWr2wwkshz2zu8-L31UrKwbZrJSBcJX-nQ@mail.gmail.com>
URL: https://gitlist.dev/e/CANWD%3DrX-MEiS4cNzDWr2wwkshz2zu8-L31UrKwbZrJSBcJX-nQ%40mail.gmail.com
In-Reply-To: <CANWD=rWmzgAwTp=E_1=th0Myk-dh4m5Y9PE3=fpHeirsVVQKwQ@mail.gmail.com>

```
Hi all,

Someone pointed out on the "Git for human beings" Google group
(https://groups.google.com/d/topic/git-users/27_FxIV_100/discussion)
that using git-reset's hard mode when having staged untracked files
simply deletes them from the working dir.

Since git-reset specifically doesn't touch untracked files, one could
expect having staged untracked files reset to their previous
"untracked" state rather than being deleted.

Could this be a bug or a missing feature? Or if it isn't, can someone
explain what we got wrong?
Cheers

--
Pierre-François CLEMENT
Application developer at Upcast Social

```

## David Kastrup, 2014-06-09 14:04

Subject: Re: Git reset --hard with staged changes
Message-ID: <87vbsayy9w.fsf@fencepost.gnu.org>
URL: https://gitlist.dev/e/87vbsayy9w.fsf%40fencepost.gnu.org
In-Reply-To: <CANWD=rX-MEiS4cNzDWr2wwkshz2zu8-L31UrKwbZrJSBcJX-nQ@mail.gmail.com>

```
Pierre-François CLEMENT <likeyn@gmail.com> writes:

> Hi all,
>
> Someone pointed out on the "Git for human beings" Google group
> (https://groups.google.com/d/topic/git-users/27_FxIV_100/discussion)
> that using git-reset's hard mode when having staged untracked files
> simply deletes them from the working dir.
>
> Since git-reset specifically doesn't touch untracked files, one could
> expect having staged untracked files reset to their previous
> "untracked" state rather than being deleted.
>
> Could this be a bug or a missing feature? Or if it isn't, can someone
> explain what we got wrong?

git reset --keep maybe?

In a work dir and index without modifications, I expect

git apply --index ...
git reset --hard

to remove any files that git apply created.  It would not do so using
your proposal.  I agree that it seems a bit of a borderline, but I
consider it better that once a file _is_ tracked, git reset --hard will
first physically remove it before untracking it.

-- 
David Kastrup

```

## Pierre-François CLEMENT, 2014-06-09 23:22

Subject: Re: Git reset --hard with staged changes
Message-ID: <CANWD=rVB249Vu1QMk64V+FxfCfJPzxqZgCfyEuixJJ_iKoTLPQ@mail.gmail.com>
URL: https://gitlist.dev/e/CANWD%3DrVB249Vu1QMk64V%2BFxfCfJPzxqZgCfyEuixJJ_iKoTLPQ%40mail.gmail.com
In-Reply-To: <87vbsayy9w.fsf@fencepost.gnu.org>

```
2014-06-09 16:04 GMT+02:00 David Kastrup <dak@gnu.org>:
> Pierre-François CLEMENT <likeyn@gmail.com> writes:
>
>> Hi all,
>>
>> Someone pointed out on the "Git for human beings" Google group
>> (https://groups.google.com/d/topic/git-users/27_FxIV_100/discussion)
>> that using git-reset's hard mode when having staged untracked files
>> simply deletes them from the working dir.
>>
>> Since git-reset specifically doesn't touch untracked files, one could
>> expect having staged untracked files reset to their previous
>> "untracked" state rather than being deleted.
>>
>> Could this be a bug or a missing feature? Or if it isn't, can someone
>> explain what we got wrong?
>
> git reset --keep maybe?
>
> In a work dir and index without modifications, I expect
>
> git apply --index ...
> git reset --hard
>
> to remove any files that git apply created.  It would not do so using
> your proposal.  I agree that it seems a bit of a borderline, but I
> consider it better that once a file _is_ tracked, git reset --hard will
> first physically remove it before untracking it.
>
> --
> David Kastrup

Hm, I didn't think of "git apply --index"... Makes sense for this
special use, but I'm not sure about the other use cases. Consider this
scenario:

You create a new (untracked) file.
You use git-reset's hard mode to go one commit back, the new
(untracked) file's still there.
You add/stage that new file.
You use git-reset's hard mode again to go one commit back, and the new
untracked file you just staged gets deleted.

Also, according to Git-scm
(http://git-scm.com/book/en/Git-Basics-Recording-Changes-to-the-Repository):

"Tracked files are files that were in the last snapshot [...].
Untracked files are everything else."

So it seems to me like staged untracked files shouldn't be considered
as tracked files, and thus shouldn't be removed. Or maybe, git-reset's
hard mode should always delete everything including untracked files?
It would also make sense, given the numerous modes it has.

--
Pierre-François CLEMENT
Application developer at Upcast Social

```

## Junio C Hamano, 2014-06-09 23:28

Subject: Re: Git reset --hard with staged changes
Message-ID: <xmqq61k9d5nk.fsf@gitster.dls.corp.google.com>
URL: https://gitlist.dev/e/xmqq61k9d5nk.fsf%40gitster.dls.corp.google.com
In-Reply-To: <CANWD=rVB249Vu1QMk64V+FxfCfJPzxqZgCfyEuixJJ_iKoTLPQ@mail.gmail.com>

```
Pierre-François CLEMENT <likeyn@gmail.com> writes:

> Hm, I didn't think of "git apply --index"... Makes sense for this
> special use, but I'm not sure about the other use cases.

Try merging another branch that tracks a file your current branch
does not know about and ending up with conflicts during that merge.
Resetting the half-done result away must remove that new path from
your working tree and the index.

```

## Dale Worley, 2014-06-10 01:03

Subject: Re: Git reset --hard with staged changes
Message-ID: <loom.20140610T025754-449@post.gmane.org>
URL: https://gitlist.dev/e/loom.20140610T025754-449%40post.gmane.org
In-Reply-To: <CANWD=rVB249Vu1QMk64V+FxfCfJPzxqZgCfyEuixJJ_iKoTLPQ@mail.gmail.com>

```
From: Pierre-François CLEMENT <likeyn <at> gmail.com>
> You create a new (untracked) file.
> You use git-reset's hard mode to go one commit back, the new
> (untracked) file's still there.
> You add/stage that new file.
> You use git-reset's hard mode again to go one commit back, and the new
> untracked file you just staged gets deleted.
> 
> Also, according to Git-scm
> (http://git-scm.com/book/en/Git-Basics-Recording-Changes-to-the-Repository):
> 
> "Tracked files are files that were in the last snapshot [...].
> Untracked files are everything else."
> 
> So it seems to me like staged untracked files shouldn't be considered
> as tracked files, and thus shouldn't be removed. Or maybe, git-reset's
> hard mode should always delete everything including untracked files?
> It would also make sense, given the numerous modes it has.

There's a core question that must be answered:  What, *exactly*, is a
"tracked file"?

If you look at that passage in the book, it continues:

"Tracked files are files that were in the last snapshot; they can be
unmodified, modified, or staged. Untracked files are everything else — any
files in your working directory that were not in your last snapshot and are
not in your staging area."

But if you look carefully, that passage gives two definitions of "untracked
files", and *they don't agree*, specifically in the case of a file that is
in the index but not in the base commit.  And that's the case we're considering.

To fix this, you've got to figure out what the definition of "tracked file"
is supposed to be, and then ensure that everything (code and documentation)
is consistent with that.

(As far as I can tell from Git's behavior, the definition of tracked file is
"any file that is in the base commit or in the index".  Based on that
definition, "git reset --hard" is working as documented.)

Dale

```

## Junio C Hamano, 2014-06-10 05:44

Subject: Re: Git reset --hard with staged changes
Message-ID: <xmqqsindb9nu.fsf@gitster.dls.corp.google.com>
URL: https://gitlist.dev/e/xmqqsindb9nu.fsf%40gitster.dls.corp.google.com
In-Reply-To: <loom.20140610T025754-449@post.gmane.org>

```
Dale Worley <worley@alum.mit.edu> writes:

> (As far as I can tell from Git's behavior, the definition of tracked file is
> "any file that is in the base commit or in the index".  Based on that
> definition, "git reset --hard" is working as documented.)

The book (whichever book you guys are talking about) is wrong, if it
considers only the paths in the HEAD commit tracked.  After the user
deliberately does "git add" a path not in HEAD, the user runs any
command (e.g. "git apply --index", "git cherry-pick --no-commit")
that may bring a path not in HEAD to the result without recording a
new commit that updates the HEAD, a new path is recorded in the
index and that path is considered "tracked" before the resulting
contents in the index is made into a commit.

```

## Pierre-François CLEMENT, 2014-06-10 14:59

Subject: Re: Git reset --hard with staged changes
Message-ID: <CANWD=rUz9Wgoktp7-NkQMvWDmYOPv0kMqUNoe4FPJ9+Ax_UJBA@mail.gmail.com>
URL: https://gitlist.dev/e/CANWD%3DrUz9Wgoktp7-NkQMvWDmYOPv0kMqUNoe4FPJ9%2BAx_UJBA%40mail.gmail.com
In-Reply-To: <xmqq61k9d5nk.fsf@gitster.dls.corp.google.com>

```
2014-06-10 1:28 GMT+02:00 Junio C Hamano <gitster@pobox.com>:
> Pierre-François CLEMENT <likeyn@gmail.com> writes:
>
>> Hm, I didn't think of "git apply --index"... Makes sense for this
>> special use, but I'm not sure about the other use cases.
>
> Try merging another branch that tracks a file your current branch
> does not know about and ending up with conflicts during that merge.
> Resetting the half-done result away must remove that new path from
> your working tree and the index.

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?
--
Pierre-François CLEMENT
Application developer at Upcast Social

```

## David Kastrup, 2014-06-10 15:27

Subject: Re: Git reset --hard with staged changes
Message-ID: <871tuwss2p.fsf@fencepost.gnu.org>
URL: https://gitlist.dev/e/871tuwss2p.fsf%40fencepost.gnu.org
In-Reply-To: <CANWD=rUz9Wgoktp7-NkQMvWDmYOPv0kMqUNoe4FPJ9+Ax_UJBA@mail.gmail.com>

```
Pierre-François CLEMENT <likeyn@gmail.com> writes:

> 2014-06-10 1:28 GMT+02:00 Junio C Hamano <gitster@pobox.com>:
>> Pierre-François CLEMENT <likeyn@gmail.com> writes:
>>
>>> Hm, I didn't think of "git apply --index"... Makes sense for this
>>> special use, but I'm not sure about the other use cases.
>>
>> Try merging another branch that tracks a file your current branch
>> does not know about and ending up with conflicts during that merge.
>> Resetting the half-done result away must remove that new path from
>> your working tree and the index.
>
> 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

```

## Pierre-François CLEMENT, 2014-06-10 16:30

Subject: Re: Git reset --hard with staged changes
Message-ID: <CANWD=rWRT1iarnZzyd75g6gr0nyo3rrdH01j+Bjq0t4q2UUhhg@mail.gmail.com>
URL: https://gitlist.dev/e/CANWD%3DrWRT1iarnZzyd75g6gr0nyo3rrdH01j%2BBjq0t4q2UUhhg%40mail.gmail.com
In-Reply-To: <871tuwss2p.fsf@fencepost.gnu.org>

```
2014-06-10 17:27 GMT+02:00 David Kastrup <dak@gnu.org>:
> Pierre-François CLEMENT <likeyn@gmail.com> writes:
>
>> 2014-06-10 1:28 GMT+02:00 Junio C Hamano <gitster@pobox.com>:
>>> Pierre-François CLEMENT <likeyn@gmail.com> writes:
>>>
>>>> Hm, I didn't think of "git apply --index"... Makes sense for this
>>>> special use, but I'm not sure about the other use cases.
>>>
>>> Try merging another branch that tracks a file your current branch
>>> does not know about and ending up with conflicts during that merge.
>>> Resetting the half-done result away must remove that new path from
>>> your working tree and the index.
>>
>> 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

Yeah sorry, I just noticed the emails on the definition of what are
(un)tracked files
(http://thread.gmane.org/gmane.comp.version-control.git/251071/focus=251151),
as I didn't get them in my inbox for some reason. So staged files
which aren't in HEAD are also considered tracked -- which explains it
all. Someone told me that too on the "Git for human beings" Google
Group, but 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

```
