uso

雑記いろいろ
★書いてある内容に保証は一切ありません。
 ご自身で判断をしてください。

Gitのcore.ignorecaseについて

2024-06-26 13:20:48 | work
Gitのcore.ignorecaseについてハマったのでメモ

・core.ignorecase=true : gitのあらゆる動作において、大文字小文字の識別を無視する
・core.ignorecase=false : gitのあらゆる動作において大文字小文字を識別する

設定を確かめるコマンド
git config -l --local | grep core.ignorecase

★Ver2.45.0のGitリファレンスのGoogle翻訳
core.ignoreCase
さまざまな回避策により、GitがAPFS、HFS+、FAT、NTFSなど、大文字と小文字を区別しないファイルシステムでよりよく機能できるようにする内部変数。
たとえば、Gitが「Makefile」を期待しているときにディレクトリリストが「makefile」を見つけた場合、
Gitはそれが実際に同じファイルであると仮定し、引き続き「Makefile」として記憶します。
デフォルトはfalseですが、git-clone[1]またはgit-init[1]は、リポジトリの作成時に必要に応じてcore.ignoreCaseをプローブしてtrueに設定します。
Gitは、オペレーティングシステムとファイルシステムのために、この変数の適切な構成に依存しています。この値を変更すると、予期しない動作が発生する可能性があります。

>デフォルトはfalse
>Gitは、オペレーティングシステムとファイルシステムのために、この変数の適切な構成に依存しています。
自分の持っている環境を調べた結果
・Windows11:true
・MacOS:true
・WSL(Win11の):false ※というか設定なし
OSやファイルシステムに依存して設定が変わっているみたい。

大文字小文字を無視(true)だと、ファイル名やディレクトリ名、ブランチ名も大文字小文字を無視してしまう。
そのため、ファイル名を間違えた場合、修正してアップしても、差分とならない(修正したことにならない)。

この問題に対処するために、設定をfalseにする、それを推奨するという記事を多々見かけたが、一旦アップしたファイルを削除してあげなおすのが正しいと思う。
リファレンスの最後に改訂あるこの一文が理由。
>この値を変更すると、予期しない動作が発生する可能性があります。

Windowsで開発してる人が、HOGE.htmlとhoge.htmlを共存させることができないのに、
別の人がWSLでそれをやってプッシュして通って、Windows環境の人がバグる、という事態になる。
 →そもそも開発環境の前提がどうなっているか理解した上で、開発者は開発しているので、こんな事態予測できるはず。
 →メモ書きでfalseにしている人は、そうしても問題ないという前提の開発環境であることを明記していないだけなのか?

なんとなく、すぐにfalseに設定とか、デフォルトをfalseにすればいいのに、という記載が多いから気になったので書いてみたが、この主観はあっているか?

---ここからがハマった内容

1)誰かが大文字小文字違いのブランチをリモートにプッシュした
  リモートリポジトリのブランチA
  リモートリポジトリのブランチa
  →これを実現した方法がよくわからない
   Pushする際に同じ名称のブランチだからダメとエラーになってもよさそうなのだが、こうなってしまっている。なぜ?
2)久しぶりにリポジトリをPullした人が、2つのリモートブランチを取り込んだ(この時はエラーにならなかったのだと思う)
3)その後、2)の人がまたfetchやpullをしようとするとエラーになった
  問題のリポジトリ名云々 ・・・but excepted・・・云々 (unable toupdate local ref)
4)困って相談された(私)
  私の環境では、リモートブランチAしかない
  そこでPullすると(エラーにならない)、リモートブランチAがなくなり、リモートブランチaがnew branchとして作成される
  Pullするたびに、ブランチA→ブランチa→ブランチA・・・と入れ替わり続けるだけ

3)と4)の挙動の違いはなんなのか?それは、1)の状態がどうやって生まれたかが仮説なので、確証はないが、予想するとこんな感じ
・誰かがブランチAを作成してPushした
・私がfetch -pとかした(毎日何度もやっているので)
・次の日、誰かがブランチaを作成してPushした(エラーにならなかったのか?)
・次の日、私がfetch -pとかした(毎日何度もやっているので)
 →私の環境はブランチAとブランチaの識別を無視するので、ブランチAはブランチaに変わる
・3)でエラーになった人が、Pullした
 →リモートブランチAとaを取り込んだ(同じブランチ名が共存している状態を作り出した)
・3)の人がもう一度Pullした→エラー

ではないか?経験してみると、カオスだが、振り返ると喜劇っぽい。
ちなみにブランチAとaがつくられたタイミングが知りたくて調べてら、こんなコマンドがあった。
# 誰のブランチか簡単にチェックできる
% git for-each-ref --format='%(committerdate) %09 %(authorname) %09 %(refname)'
これのおかげで、ブランチの更新日が1日違いであることがわかった。

ありがとうございます。
https://tech.aainc.co.jp/archives/8323

最新の画像もっと見る