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

Re: "git checkout foo" is getting confused by folder named "foo"

From
JSJona Christopher Sahnwaldt <jc@sahnwaldt.de>
Date
Sep 25, 2013, 16:24 UTC
Message-ID
<CAEQewpoD2VRVtpEyG121TqAptoYfEXxt57CCthBX_EfN7LU0fQ@mail.gmail.com>
In-Reply-To
<vpqzjr1ujyn.fsf@anie.imag.fr>
Hi everyone,

tl;dr: The short form "git checkout foo" is a mess. There's simply too much "DWIM" magic going on. There are no comprehensible rules how it decides if "foo" is a pathspec or a refspec.

On 25 September 2013 15:09, Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> wrote:
Show 27 quoted lines
> Jona Christopher Sahnwaldt <jc@sahnwaldt.de> writes:
>
>> On 25 September 2013 04:51, David Aguilar <davvid@gmail.com> wrote:
>>> On Tue, Sep 24, 2013 at 2:07 PM, Jona Christopher Sahnwaldt
>>> <jc@sahnwaldt.de> wrote:
>>>> Hi,
>>>>
>>>> maybe this has already been reported, but I didn't find it in the mail archive.
>>>>
>>>> If I understand correctly, after I clone a repo, I should be able to
>>>> switch to branch foo just by running
>>>>
>>>> git checkout foo
>>>>
>>>> This doesn't seem to work if a folder called "foo" exists in the root
>>>> of the repo.
>>>
>>> git checkout foo --
>>
>> Thanks for the suggestion, but it doesn't work for me. With both
>> 1.7.9.5 and 1.8.3.2, I get this:
>>
>> $ git checkout wiktionary --
>> fatal: invalid reference: wiktionary
>
> OK, what happens is that "git checkout wiktionary" is actually a
> shorthand for "git checkout -b wiktionary --track origin/wiktionary".

No, it isn't. More precisely: if branch "foo" is not yet in .git/config, but there is a branch "origin/foo" and no file/folder "foo" in the root of the project, then "git checkout foo" is short for "git checkout -b foo -t origin/foo" (which in turn can be shortened to "git checkout -t origin/foo", if I understand correctly).

Below are the rather arcane rules that I found in 1.7.9.5. They apply if the branch "foo" is not yet configured in .git/config. If branch "foo" is in .git/config I guess "git checkout foo" will always check out branch "foo", no matter if there's a file called "foo" somewhere.

I gave up testing them in 1.8.3.2, but I assume its behavior the same.
Let's consider several scenarios:
1. there is a branch "origin/foo", but also a *tracked* file/folder
"foo" in the *root* folder of the project:

a. when I'm in the root folder, "git checkout foo" silently resets the working tree file/folder "foo" to its staged / HEAD version (I think) and prints no response.

b. when I'm in a sub-folder that contains a tracked file/folder called "foo", "git checkout foo" silently resets the working tree file/folder "foo" to its staged / HEAD version and prints no response

c. when I'm in a sub-folder that cotains *no* *tracked* file/folder called "foo", "git checkout foo" does nothing and prints "error: pathspec 'foo' did not match any file(s) known to git."

2. there is a branch "origin/foo", but also an *untracked* file/folder
"foo" in the *root* folder of the project:

a. when I'm in the root folder, "git checkout foo" does nothing and prints "error: pathspec 'foo' did not match any file(s) known to git."

b. when I'm in a sub-folder containing a *tracked* file/folder "foo", "git checkout foo" silently resets the working tree file/folder "foo" to its staged / HEAD version and prints no response

c. when I'm in a sub-folder that contains *no* *tracked* file/folder called "foo", "git checkout foo" does nothing and prints "error: pathspec 'foo' did not match any file(s) known to git."

3. there is a branch "origin/foo", but *no*  file/folder "foo" in the
*root* folder of the project:

a. if I'm in the root folder (no tracked or untracked file/folder "foo"), "git checkout foo" switches to branch "foo" which tracks "origin/foo":

b. if I'm in a sub-folder with a (tracked or untracked) file/folder "foo", "git checkout foo" switches to branch "foo" which tracks "origin/foo":

4. there is *no* branch "origin/foo"

a. when I'm in root or sub-folder that contains a *tracked* file/folder called "foo", "git checkout foo" silently resets the working tree file/folder "foo" to its staged / HEAD version and prints no response

b. when I'm in root or sub-folder that cotains *no* *tracked* file/folder called "foo", "git checkout foo" does nothing and prints "error: pathspec 'foo' did not match any file(s) known to git."

All right, I guess there are more cases, but let's leave it at that...
>
> In other words, it does not only "checkout" the branch, but it creates a
> local branch with the right name, and checks it out.
No, in my case, it doesn't, because there is a folder called "wiktionary".
Show 16 quoted lines
>
> The -- disables this shorthand. I'd consider this as a bug. I've just
> sent a patch to try to fix this.
>
>> When I try the full branch name:
>>
>> $ git checkout origin/wiktionary --
>> Note: checking out 'origin/wiktionary'.
>> You are in 'detached HEAD' state. You can [...]
>
> This actually checks out the right commit, but does not create a local
> branch. That's not a very desirable solution.
>
> In short, this should do the trick:
>
>   git checkout -b wiktionary --track origin/wiktionary

Yes, I know, as I said in my original mail. By the way, I later found that I can shorten this to "git checkout -t origin/wiktionary".

JC
>
> --
> Matthieu Moy
> http://www-verimag.imag.fr/~moy/
Previous: Matthieu MoyNext: Matthieu Moy
Message 7 of 11 in “"git checkout foo" is getting confused by folder named "foo"”
  1. Jona Christopher SahnwaldtSep 24, 2013
  2. David AguilarSep 25, 2013
  3. Keshav KiniSep 25, 2013
  4. Duy NguyenSep 25, 2013
  5. Jona Christopher SahnwaldtSep 25, 2013
  6. Matthieu MoySep 25, 2013
  7. Jona Christopher SahnwaldtSep 25, 2013
  8. Matthieu MoySep 25, 2013
  9. Jona Christopher SahnwaldtSep 25, 2013
  10. Matthieu MoySep 25, 2013
  11. Jona Christopher SahnwaldtSep 26, 2013

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.