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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxx> wrote:
> Jona Christopher Sahnwaldt <jc@xxxxxxxxxxxx> writes:
>
>> On 25 September 2013 04:51, David Aguilar <davvid@xxxxxxxxx> wrote:
>>> On Tue, Sep 24, 2013 at 2:07 PM, Jona Christopher Sahnwaldt
>>> <jc@xxxxxxxxxxxx> 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".

>
> 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/
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]