一下子敏感, 一下子不敏感, Git 你搞得我好亂啊

概述

在一個因緣際會之下, 我與 Git 有場美麗的邂逅, 殊不知, 對我這個情場處子來說, Git 就像一隻貓, 忽遠忽近, 忽冷忽熱, 忽上忽下, 忽快忽慢… 一下子敏感, 一下子又不敏感, 那個… 我說的是大小寫。



故事開始

什麼是 case-sensitivecase-insensitive? 就是大小寫敏感 以及 大小寫不敏感!

不同的作業系統對於 case-sensitiveness 這件事情會有不同的設定, 拿 case-sensitive 的 Linux 來說, 在同一個資料夾我可以有檔案 a 跟檔案 A, 但是在 case-insensitive 的 MacOS 中, 檔案 aA

試想, 在 Linux 中我在一個資料夾內有兩個檔案為 aA, 並且我都上了 commit 並推上遠端, 那這時在 MacOS 上將如何呈現這件事呢?
macOS 視角: Commit 裡面有幾個我不管, 對我來說只有 一個 檔案, 因為 aA

媽媽樂勒, 你搞得我好亂啊! 該如何解決這件事情呢? 我們可以使用 git 指令

git config [--local/--global] core.ignorecase true/false

這個指令是在幹什麼的勒?
它可以決定 Git 的世界是 如何看待 case-sensitiveness(大小寫敏感度) 這件事。

舉例來說, 在一個 git 專案中, 當我們今天設定為 true, 代表 case-insensitive

git config --local core.ignorecase true

這時候如果我們在 macOS 中變更檔名:

mv a A

將原本控管中的一個 a 更名為 A, 這時候呢, 對 case-insensitive 的 macOS 來說檔案還是只有一個, 只是檔名變了, 所以什麼事都沒有改變。

同理, 對此設定的 Git 來說也是一樣的; 資料夾中不管是 A 還是 a, 對 Git 來說都是一個檔案, 因為目前的設定是 case-insensitive(大小寫不敏感), 所以如果我們使用以下指令檢查狀態:

git status

我們是不會看到有任何 modified 的檔案的

但如果這時 Git 的設定為 false, 即 case-sensitive(大小寫敏感), 老天爺… 那就是完全不一樣的事了。
先設定:

git config --local core.ignorecase false

再改個檔名:

mv a A

然後看個狀態:

git status

這時我們會發現, 多了一個 new file A ! 因為這時 Git 的角度是 case-sensitive(大小寫敏感), a 對我來說是一個檔案, A 是另一個檔案, 所以我的 commit 中並不存在 A 這個檔案。

更有趣的事情, 使用

git add .

然後新增一個 commit:

git commit -m 'Add A'

這時在變更一次檔名:

mv A a

然後檢視狀態:

git status

此時我們可以發現, 已經不會有任何提示 modified 了, 因為此時在 Git 的 commit 中存有兩個檔案, 一個是 a, 一個是 A, 所以兩個我都有, 自然不會出現 modified 了

若要驗證這一點, 可以先在 GitHub 建立一個 repo, 然後將目前這個分支推上 GitHub, 再到 GitHub 上去看, 會發現…

傻眼貓咪勒… 我的資料夾內明明就只有一個檔案, 怎麼上了 GitHub 之後變兩個了?

再來, 我們試著變更這個檔案:

vim a

隨便加個 “123” 之類的, 然後儲存並離開:

:wq

再檢視一下狀態:

git status

嚇死寶寶, 竟然發現同時出現了 modified: A 以及 modified: a!!! 因為此時在 Git 的世界中是有兩個檔案的, 兩個都對應到資料夾中的檔案 a

有興趣的話, 你可以再做個實驗, 如果你有 Linux 系統的主機的話, 可以開一個專案, 使用以下指令來建立兩個檔案:

touch a A

初始化 Git

git init

做一個 commit

git add .
git commit -m 'init'

先在 GitHub 上面開一個 repo, 然後推到遠端:

git remote add origin yourRepoURL
git push -u origin master

這時候你可以到遠端看看, 遠端的資料夾內應該是確實會有 aA 兩個檔案, 因為 Linux 系統是 case-sensitive(大小寫敏感)

現在找一台 macOS 的電腦來 clone 專案:

git clone yourRepoURL

進到專案內

cd yourProject

檢視資料夾內容:

ls

林周公勒! 我剛剛明明就有看到兩個檔案, 阿怎麼少了一個?
你應該只會看到 a 檔案, 因為 macOS 檔案系統是 case-insensitive

綜合以上所得, 我歸納出以下幾點:

  • 佛曰一沙一世界, 獨自開發時, 請務必讓你的 Git config case-sensitiveness 的設定跟你的作業系統是一致的, 這樣至少兩邊行為一樣, 才不會把自己搞到精神錯亂啊!
  • 如果 Git 設定為 case-insensitive, 那麼儘管你實際上有兩個大小寫不同, 但檔名相同的檔案, Git 只會視為一個。
  • 如果 Git 設定為 case-sensitive, 那麼儘管你只是使用 mv 做小寫更名成大寫的動作, Git 還是會當作是有兩個不同的檔案
  • 一個專案如果參與的開發者們橫跨了不同的作業系統, 那請一定要在這一點上有共識, 同一個資料夾內不要有同檔名但大小寫不同的檔案, 不然是想逼死誰?
  • 如果遇到需要重新命名檔名的話, 記得確保修改的是 commit 內 的檔名, 務必使用 git mv currentFileName newFileName

Q&A

這邊將一些概念歸納成 Q&A 的方式, 希望可以幫助理解

  • 在 Git 中, 當我們設定 git config --local core.ignorecase true 時, 此時 git 為 case-sensitive 或 case-insensitive?
    case-insensitive

  • 在 Git 中, 當我們設定 git config --local core.ignorecase false 時, 此時 git 為 case-sensitive 或 case-insensitive?
    case-sensitive

  • macOS 的檔案系統是 case-insensitive 還是 case-sensitive?
    case-insensitive

  • Linux 的檔案系統是 case-insensitive 還是 case-sensitive?
    case-sensitive

  • 為什麼 Git 的 case-sensitiveness 跟作業系統的視角要一致?
    這樣才會兩邊的行為一致



結論

天下無不散的宴席, 送君千里終須一別, 將琴寄語兮, 予以相將…
不好意思讓你們聽到髒東西… 大家新年快樂!

最後

人非聖賢, 孰能無過… 阿不是, 是人非草木, 豈能無情…
你清脆的掌聲於我, 有如浪頭與衝浪者的關係! 讓我找到存在的價值…

拍 1 下: 來都來了, 刻個到此一遊吧!
拍 10 下: 覺得小生寫得還可以, 馬馬虎虎普普通通淒淒慘慘戚戚...
拍 20~30 下: 這篇文章有幫助到你, 讓你的概念清晰了百分之零點零零一
拍 40~50 下: 看完覺得心情愉悅, 或是覺得 Ray 很帥
Kubernetes - Resources Limit Laravel - EloquentORM - Relationships

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×