# "git checkout" resets modified files

3 messages from 2015-08-29 to 2015-08-29. Participants: Steve Heyns, Junio C Hamano.
Thread: https://gitlist.dev/t/40214

## Steve Heyns, 2015-08-29 06:15

Subject: "git checkout" resets modified files
Message-ID: <CANDob0LdQpoSfsedPK_yhNunXBvNTc9L1zKOM9h8dBUDePs0kg@mail.gmail.com>
URL: https://gitlist.dev/e/CANDob0LdQpoSfsedPK_yhNunXBvNTc9L1zKOM9h8dBUDePs0kg%40mail.gmail.com

```
"git checkout" resets modified files

Version git  2.5.0,

Description:
I was automating a process that would pull and switch to another
branch when I stumbled across this. I have not been able to emulate
this from command line but using go (or I imagine other languages are
similar) if you execute a command like

exec.Command("git","checkout","")

A checkout with the branch parameter but the branch parameter is empty.

The result is git resets the the repository, modified files are reset
back to original state without warning.

I would expect the behavior should be the same as a "git checkout" command

Has anyone else seen something like this ? For myself the solution was
to simply suppress passing in the revision as a third argument if the
revision was empty. But this does appear to be an off behavior.

Thanks
Nz

```

## Junio C Hamano, 2015-08-29 07:15

Subject: Re: "git checkout" resets modified files
Message-ID: <xmqqlhcuzhsu.fsf@gitster.mtv.corp.google.com>
URL: https://gitlist.dev/e/xmqqlhcuzhsu.fsf%40gitster.mtv.corp.google.com
In-Reply-To: <CANDob0LdQpoSfsedPK_yhNunXBvNTc9L1zKOM9h8dBUDePs0kg@mail.gmail.com>

```
Steve Heyns <notzippy@gmail.com> writes:

> "git checkout" resets modified files
>
> Version git  2.5.0,
>
> Description:
> I was automating a process that would pull and switch to another
> branch when I stumbled across this. I have not been able to emulate
> this from command line but using go (or I imagine other languages are
> similar) if you execute a command like
>
> exec.Command("git","checkout","")
>
> A checkout with the branch parameter but the branch parameter is empty.

It is not feeding an empty branch parameter [*1*].  It is asking Git
to check out all paths that match a pathspec "" out of the index.

Now, arguably, the user who would want to match everything may be
more likely to give "." as the pathspec (or if she is not at the
root of the working tree, ":/"), but "" means the same thing as ".",
and the requested behaviour "check out all that match this pathspec
from the index" would essentially mean "I want to get rid of all the
modification in my working tree relative to the index".

I do not think this behaviour depends on the vintage of Git.  An
empty string as pathspec has always matched "everything in here"
AFAIR.


[Footnote]

*1* Checking out a branch whose name is an empty string can be asked
    explicitly by disambiguating double-dash like this:

    $ git checkout "" --

And it will be answered (correctly) with:

    fatal: invalid reference

```

## Junio C Hamano, 2015-08-29 07:58

Subject: Re: "git checkout" resets modified files
Message-ID: <xmqqh9nizfue.fsf@gitster.mtv.corp.google.com>
URL: https://gitlist.dev/e/xmqqh9nizfue.fsf%40gitster.mtv.corp.google.com
In-Reply-To: <xmqqlhcuzhsu.fsf@gitster.mtv.corp.google.com>

```
Junio C Hamano <gitster@pobox.com> writes:

> I do not think this behaviour depends on the vintage of Git.  An
> empty string as pathspec has always matched "everything in here"
> AFAIR.

Having said all that, I think the DWIM used by "git checkout" has
some room for improvement, namely, its "we didn't see a double-dash;
is it a ref or is it a pathspec?" disambiguation should become
similar to the revision parser's.

Notice that

    $ git log ""

will error out, saying that an empty string does not name either a
revision or an existing path in the working tree.  I think the same
"refusal due to ambiguity" should be in "git checkout" when the user
says

    $ git checkout ""

Right now, when there is no double-dash, the code checks if the
first token X can be DWIMmed as a ref.  It may either name an
existing branch X, or it may be a non-existing branch name, but
there is a single remotes/Y/X and the user is too lazy to say 'git
checkout -t -b remotes/Y/X X' and instead said 'git checkout X'.

And if the first token X cannot be DWIMmed as a ref according to the
above logic, unlike the revision parser, we do not check it (and all
the subsequent tokens) name existing filesystem entity.

I think we really should.  With that, Steve's command line would
have correctly diagnosed as a liely error.

Of course, that still allows people to say

    $ git checkout -- ""

if they really mean it, but they can type

    $ git checkout -- :/

just as easily, so there is no big loss.

After following the existing code myself, I think this is a rather
easy low-hanging fruit for any aspiring Git hacker.  Hint, hint...


> [Footnote]
>
> *1* Checking out a branch whose name is an empty string can be asked
>     explicitly by disambiguating double-dash like this:
>
>     $ git checkout "" --
>
> And it will be answered (correctly) with:
>
>     fatal: invalid reference

```
