前篇文章介紹過怎麼用 Visual Studio 將修改「Check In」(嚴格來說是 Stage + Commit + Push)進 Git 版控,這篇聊聊 TFVC 轉換 Git 要花點時間適應的一件事 - 充滿神祕色彩,與 TFVC 大不相同的 Branch (分支)。

TFVC 切 Branch 的方法很簡單但很笨,就是複製一份拿來改。例如,主要維護版本 MAIN/MyProject 要加新功能,我想切個 Branch 放心大改,不想擔心把原來程式搞壞,於是我建立一個 DEV Branch,TFS 工作目錄將新增 DEV/MyProjects,裡面有跟 MAIN/MyProject 一樣的內容,等寫完測試無誤,再 Merge (合併) 回 MAIN。 這套做法在 TFS 行之有年,感覺沒什麼不對,不同 Branch 不同目錄,清清楚楚不會搞混,但每切一個 Branch 整個 Solution 的檔案就得複製一份,一分檔案包含 packages 資料夾往往數百 MB 起跳,一來浪費空間,二來複製費時,再來若工作目錄冒出一堆 「加功能A」、「加功能B」、「改BugX」、「改BugY」的 Branch 專屬資料夾,看了還蠻煩的。於是 TFS 使用者都默默養成好習慣,愛惜地球資源,沒事不亂開 Branch。

仔細想想,這不太對吧? 一個 Branch 開一個資料夾,跟沒有版控系統時代用 Source20190601、Source20190605 資料夾管理版本的做法有 87 分像,很簡單易懂沒錯,但有點笨。

Git 在 Branch 上採取截然不同的思維,你可以想像成 Git 滲透了檔案系統,在其中加入黑魔法,無論你建立再多條 Branch,都只會看到一個工作資料夾。當你切換到 Branch A 時,工作資料夾的檔案就會變成 Branch A 的樣子;切換到 Branch B 時,工作資料夾的檔案瞬間換成 Branch B 的狀態。因此,Git 建 Branch 的成本很低,期望開發者善用它有效管理版本。

聽起來有點抽象,用實例來說明。

假設版控一開始只有主 Branch 叫 master,我們接到命令要在 HomeController.cs 加上一個新 View,決定開一個新的 Branch 來進行這項擴建工程。

新增 Branch 的做法有好幾種:Team Explorer - Branches 介面有個 New Branch 鈕、 master 分支右鍵選單有「New Local Branch from...」選項,或 Visual Studio 狀態列最右側有個所在分支顯示,按向上鍵箭頭選單有「New Branch...」選項。如以下示範,我們從 master 產生一個新分支「feature/add-view」:

Branch 命名有個小訣竅,可用 / 分隔線讓 Visual Studio 分類顯示,例如:feature/add-view、feature/support-oath 會顯示在 feature 資料夾下,fix/busy-crash、fix/idle-down 會顯示在 fix 資料夾:(如下圖黃框)

順便說說如何確認目前所在 Branch。Git 可以快速切換不同 Branch,有時切來切去會忘了自己現在在哪條 Branch 上, 改錯版本 Commit 錯 Branch 就糗了。因此,時時知道目前在哪條 Branch 很重要。Team Explorer - Branches 的儲存庫名稱旁括號內顯示的就是目前所在 Branch(上圖1標示處),但更方便的資訊來源在 Visual Studio 狀態列右側(上圖2標示處),讓你隨時隨地都知道自己在哪條 Branch 上,不要迷路。

至於要切換 Branch,在 Team Explorer - Branches 的特定 Branch 項目上點兩下可以完成切換,或是按狀態列右側目前 Branch 名稱右側箭頭叫出選單直接點 Branch 名稱(上圖橘框)進行切換更快。

回到剛才的實例,假設我們切到 feature/add-view Branch,修改專案,在 HomeController.cs 加入 AcitonResult NewView() 及 Views/Home/NewView.cshtml,並 Commit 進版控。

接著是見證奇蹟的時刻,我們觀察 Solution Explorer,焦點放在 feature/add-view Branch 新增的 Views/Home/NewView.cshtml,使用狀態列右側的 Branch 清單切換回 master,Solution Explorer 閃一下,Views/Home/NewView.cshtml 消失,這是因為該檔只被加入 feature/add-view Branch,對原本的 master Branch 來說還不存在。隨後,我們再將 Branch 切回 feature/add-view Branch,NewViews.cshtml 又回來了。

而魔術般的切換並不是 Visual Studio 做了什麼,而是實體檔案真的改變了。將檔案總管放在 Visual Studio 下方觀察,可以看到實體檔案會隨著 Branch 切換消失或出現:

但有一點值得注意,Git 保存檔案時只關注內容變化,還原檔案時並不包含原始的寫入時間,故每次切換 Branch 還原檔案時檔案更新時間都會改變(如以上示範,NewView.cshtml 的時間由 2:09PM 變成 2:11PM),故應用時要避免以檔案時間作為版本比對依據。

這陣子對慣用 TFS 同事介紹 Git 時,我發現要花最多時間解釋的部分就是 Branch,畢竟它跟 TFVC 的 Branch 觀念截然不同,而檔案目錄內容變來變去的行為宛如魔法。但理解並預期 Git 切換 Branch 的檔案變化是活用 Git Branch 的重要基礎,無法逃避。

希望這篇說明能幫助 TFVC 轉換 Git 的同學掌握 Git Branch 切換行為,早日享受 Git 的便利。

Highlight the difference of branch operation between TFVC and Git and demostrating the file magic of Git branch switch.


Comments

# by 小熊子

source tree 很方便,很清楚!

# by kkbruce

自推一下自己的小筆記:https://blog.kkbruce.net/2016/03/git-branch-naming-best-practices.html

# by Jeffrey

to kkbruce,感謝分享,實用!

Post a comment


10 + 8 =