git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* Race condition on `git checkout -c`
@ 2023-01-19 21:13 Arthur Milchior
  2023-01-19 22:55 ` Chris Torek
  0 siblings, 1 reply; 3+ messages in thread
From: Arthur Milchior @ 2023-01-19 21:13 UTC (permalink / raw)
  To: git

Thank you for filling out a Git bug report!
Please answer the following questions to help us understand your issue.

What did you do before the bug happened? (Steps to reproduce your issue)
I was working on code as usual. I should note that the repo is big, so
it’s not unusual for some git operations to take half a minute.

Here is a simpler reproduction that worked on my machine.

```
mkdir g
cd g
git init
git touch a
git add a
git commit -am "a"
git checkout -b b
```

While the last command is being run, in a different terminal, run `git
checkout -b B`

I realized that I can do it manually, by just using cmd-tab, then enter.

Finally, type `git branch`


What did you expect to happen? (Expected behavior)

I expect either:
* to see an error message stating that `b` already exists
* to see `b` and `B` in the list of branch.

In any case, when both branches exists, which will be the case on
system which were started with this "bug", I expect to see both
branches listed.

What happened instead? (Actual behavior)

I was able to successively create both branches.
The branch `b` is not listed. If I check it out, then `git branch`
does not list a single branch as the current branch.

What's different between what you expected and what actually happened?

I expect that `git branch` always list me on a branch, and let me know
of all existing branch.

Anything else you want to add:

First: I can’t reproduce with `git branch b` and `git branch B`, so I
guess either `branch` is faster than `checkout -c`, or something else
is done right there.

I know that this race condition seems very contrived. In real life,
the names were `bookmarkShome` and `bookmarksHome`. Obviously, both
were supposed to be `bookmarksHome`, in camlCase. The first one was a
typo. But that was the one git show, which was confusing.
However, even if the repo is big and checking out a branch can easily
take 30 seconds, I’m still not sure when I’d have two terminals
creating branchs at the same time.

Please review the rest of the bug report below.
You can delete any lines you don't wish to share.


[System Info]
git version:
git version 2.39.0.246.g2a6d74b583-goog
cpu: x86_64
no commit associated with this build
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
feature: fsmonitor--daemon
uname: Darwin 22.2.0 Darwin Kernel Version 22.2.0: Fri Nov 11 02:03:51
PST 2022; root:xnu-8792.61.2~4/RELEASE_ARM64_T6000 x86_64
compiler info: clang: 14.0.0 (clang-1400.0.29.202)
libc info: no libc information available
$SHELL (typically, interactive shell): /bin/bash


[Enabled Hooks]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Race condition on `git checkout -c`
  2023-01-19 21:13 Race condition on `git checkout -c` Arthur Milchior
@ 2023-01-19 22:55 ` Chris Torek
  2023-01-20  9:01   ` Arthur Milchior
  0 siblings, 1 reply; 3+ messages in thread
From: Chris Torek @ 2023-01-19 22:55 UTC (permalink / raw)
  To: Arthur Milchior; +Cc: git

(Top note: you mean `git checkout -b` or `git switch -c`, not `git
checkout -c`.)

On Thu, Jan 19, 2023 at 1:24 PM Arthur Milchior
<arthur.milchior@gmail.com> wrote:
>
> I expect either:
> * to see an error message stating that `b` already exists
> * to see `b` and `B` in the list of branch.

[snip]

> uname: Darwin 22.2.0 Darwin Kernel Version 22.2.0: Fri Nov 11 02:03:51

Darwin (macOS) is your problem here.  The same problem
occurs on Windows, but not on Linux, by default.

Technically the problem is in the file system itself, combined with
the ways (plural) that Git stores branch names.

As far as Git itself is concerned, branch names are *always* case
sensitive, so branches named `b` and `B` are different.  But Git
stores branch names in two different formats, at the moment:

 * Some are kept in a plain-text file `.git/packed-refs`.
 * Some are stored as directory-and-file-names in `.git/refs/`.

If the OS's file system is case sensitive, as most standard Linux
file systems are, there's no problem with the latter. But if the OS's
file system is case-INsensitive, as the default file systems on
Windows and MacOS are, this becomes a problem: the attempt
to create both `refs/heads/b` and a different file, `refs/head/B`,
fails, with one of the two names "winning" and the other attempt
to create a new name simply re-using the existing name.

If you create a case-sensitive disk volume on your Mac, which
can be a simple click-to-mount virtual drive within your regular
case-insensitive file system, you can happily use Git without this
complication. Note that the same complication applies to file
names: Linux users can create two different, separate files
named `README.TXT` and `ReadMe.txt` in a GIt project, and
if you use the default case-insensitive macOS file system, you
won't be able to check out both files.  Using your case sensitive
volume will allow you to work with the Linux group.

If and when a future version of Git starts using reftables instead
of the file system to store branch and tag names, this particular
issue will go away, but until then, I recommend keeping a case
sensitive volume handy on your mac, and more generally,
avoiding mixing upper and lower case branch and/or file names
(at all, ever) whenever possible.  This avoids a lot of problems,
though nothing can get you past the Windows `aux.h` problem. :-)

Chris

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Race condition on `git checkout -c`
  2023-01-19 22:55 ` Chris Torek
@ 2023-01-20  9:01   ` Arthur Milchior
  0 siblings, 0 replies; 3+ messages in thread
From: Arthur Milchior @ 2023-01-20  9:01 UTC (permalink / raw)
  To: Chris Torek; +Cc: git

Thank you very much for the explanation. I’m ever so happy not to be
working at the file system level nor on cross platform app.
Alas, it’s a computer configured by work, so not only do I have no
control over the disk configuration, but I’m not even allowed to plus
external storage. So I guess I’ll just remain with the case
almost-insensitive branch. Not like I expect this to occur again in
the future.

Good luck with whatever next change git plans.

Regards,
Arthur

On Thu, Jan 19, 2023 at 11:56 PM Chris Torek <chris.torek@gmail.com> wrote:
>
> (Top note: you mean `git checkout -b` or `git switch -c`, not `git
> checkout -c`.)
>
> On Thu, Jan 19, 2023 at 1:24 PM Arthur Milchior
> <arthur.milchior@gmail.com> wrote:
> >
> > I expect either:
> > * to see an error message stating that `b` already exists
> > * to see `b` and `B` in the list of branch.
>
> [snip]
>
> > uname: Darwin 22.2.0 Darwin Kernel Version 22.2.0: Fri Nov 11 02:03:51
>
> Darwin (macOS) is your problem here.  The same problem
> occurs on Windows, but not on Linux, by default.
>
> Technically the problem is in the file system itself, combined with
> the ways (plural) that Git stores branch names.
>
> As far as Git itself is concerned, branch names are *always* case
> sensitive, so branches named `b` and `B` are different.  But Git
> stores branch names in two different formats, at the moment:
>
>  * Some are kept in a plain-text file `.git/packed-refs`.
>  * Some are stored as directory-and-file-names in `.git/refs/`.
>
> If the OS's file system is case sensitive, as most standard Linux
> file systems are, there's no problem with the latter. But if the OS's
> file system is case-INsensitive, as the default file systems on
> Windows and MacOS are, this becomes a problem: the attempt
> to create both `refs/heads/b` and a different file, `refs/head/B`,
> fails, with one of the two names "winning" and the other attempt
> to create a new name simply re-using the existing name.
>
> If you create a case-sensitive disk volume on your Mac, which
> can be a simple click-to-mount virtual drive within your regular
> case-insensitive file system, you can happily use Git without this
> complication. Note that the same complication applies to file
> names: Linux users can create two different, separate files
> named `README.TXT` and `ReadMe.txt` in a GIt project, and
> if you use the default case-insensitive macOS file system, you
> won't be able to check out both files.  Using your case sensitive
> volume will allow you to work with the Linux group.
>
> If and when a future version of Git starts using reftables instead
> of the file system to store branch and tag names, this particular
> issue will go away, but until then, I recommend keeping a case
> sensitive volume handy on your mac, and more generally,
> avoiding mixing upper and lower case branch and/or file names
> (at all, ever) whenever possible.  This avoids a lot of problems,
> though nothing can get you past the Windows `aux.h` problem. :-)
>
> Chris

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-01-20  9:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-19 21:13 Race condition on `git checkout -c` Arthur Milchior
2023-01-19 22:55 ` Chris Torek
2023-01-20  9:01   ` Arthur Milchior

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).