# 前言

這個篇章來帶大家認識版控的概念,以及常見的版控類別。

在開始之前,避免新手後續的閱讀困惑,先來介紹幾個之後會看到的名詞:

  1. 地端 / 本機 / 本地 (local):位於當前位置或靠近使用者的 設備系統
    白話來說,就是你看得到的裝置,包含眼前的主機、筆電、手機,都可以稱為地端。

  2. 遠端 / 雲端 (remote):不在使用者眼前的 設備系統,也就是你看不到的裝置,包含隔壁辦公室的主機,或是遠在 Google 機房的「雲端硬碟」之類。
    而通常遠端 / 雲端的資料,會需要透過「網路」才能從地端 (你眼前這台裝置) 存取。

  3. 儲存庫 (repository):一個用來存放 資料文件程式碼或是 其他資源 的地方,以版控系統來說,主要分成 地端儲存庫,跟 遠端儲存庫

以上三個專有名詞,是使用 Git 會頻繁出現的詞彙,同時也會是學習 Git 的關鍵詞,一時之間搞不懂的讀者,可以隨著後續的介紹內容,慢慢體會這箇中含意。

# 什麼是版本控制 (版控),以及為什麼要版控?

就定義來說:只要是能記錄專案改動的過程,並且對每次改動進行標記的行為,就叫做「版控」。

「版控」除了能讓我們追蹤歷史版本之外,還有一個目的是「保存關鍵時刻」。
這就像遊戲玩到某個里程碑要進行「存檔」一樣,如果後續關卡輸了,還可以直接從「存檔點」重來。

實務上像是不小心刪了某個檔案,或是把程式改到一個自己沒辦法復原的狀況,因為有了版控的機制,不至於完全失去重要的資料。

常見的版控方式,有以下三種

  1. 以資料夾註記版控
  2. 使用集中式版控系統
  3. 使用分散式版控系統

# 以資料夾註記版控

在初學程式階段,還不會使用 Git 時,如果練習到一個階段,想避免之後的練習改壞這包程式,十之八九會這麼操作:

  1. 先把放專案程式的資料夾,整包複製一份。
  2. 更改複製出來的資料夾名稱。
  3. 安心的修改原本的程式。

當後續又有完成功能時,準備開始往下個階段前進之前,就再重複一次上述動作。

如果要區分每一次複製的資料夾,還可以在資料夾名稱加上日期區隔:
以資料夾區隔版本

這種方式很直覺,而且很簡單,只要知道怎麼建立資料夾,就連小學生都會操作,可以說是一個不用技術門檻的版控方式。

不過這個做法有很多缺點,導致實際運用專案上並不方便:

  1. 占用硬碟空間:
    由於每寫一個版本,就要把程式整包複製起來,隨著時間推移會越來越占用硬碟空間,如果公司程式量一多,那消耗的空間會很可觀。

  2. 不易追溯歷史:
    這種版控備份方式,幾乎可以把每個資料夾視為「獨立」的專案,要在版本與版本之間切換,必須在資料夾之間穿梭,無非是浪費很多不必要的時間。

  3. 容易誤刪版本:
    這就不用多說了,人有失足馬有亂蹄,如果不小心誤刪某個資料夾,又很不小心把資源回收桶清空了 (也太不小心!!),表情大概會像這隻貓一樣慘烈…
    打完報告不小心按到刪除檔案,臉開始漸漸露出母湯的表情

  4. 不易協作:
    資料夾的版控模式如果要協作維護,唯一的做法大概是把資料夾丟雲端硬碟,團隊成員再把自己開發的版本持續丟上去。
    即使每個人都乖乖的把自己的打包好才上傳,避免蓋到別人的程式,但又會回到第二點,不容易追溯歷史的問題。

由於傳統版控方式的各種痛點,人們開始使用 儲存庫 進行版控。
依據這個概念誕生的版控系統,又可以分成兩大類:

# 集中式版控系統

# 介紹

集中式版控系統,概念是直接在遠端建立一個儲存庫,團隊專案的每一個版本資料,全部在遠端儲存庫內建立。

實際的架構看起來會是這個模式,所有開發者的資料統一彙整在儲存庫之中,自己的電腦只用來開發程式,不記錄版本。
集中式版控系統

在第一天的文章提到的 SVN (Subversion) 版控工具就是一種集中式版控系統。 (然後這段還沒開始要講 Git,讀到這邊先不要跟 Git 作聯想)

# 優點

雖然這概念聽起來跟把程式丟雲端沒兩樣,不過不同的是,「儲存庫」的設計是專門拿來版控的,每次存入的資料都要寫入 版本資訊開發者資訊,它同時也提供好的 歷程查詢 功能,方便開發者調閱版本的演進。不像雲端硬碟用途只是拿來「存放資料」,並不擅長歸納「每個資料的版本」。

除此之外,因為版控集中在遠端儲存庫,所有人員都須透過網路連線才能存取到資料,所以管理人員可以在系統中設定「各別檔案的存取權限」,就能避免上傳程式發生「我蓋你」、「你蓋我」的尷尬局面。

也因為地端的程式已經跟「版控」、「備份」脫鉤,即便失誤刪除地端程式,也可以重新從遠端重新把程式拉回來用。

看似完美的世界,還是存在著缺點。

# 缺點

雖然統一把版控歷程建立在遠端儲存庫十分方便,但問題是遠端儲存庫永遠需要有網路才能操作。

換言之,舉凡一切有關版控的行為,包含發佈版本、調閱紀錄,只要沒有網路,就無法執行。

可能有讀者會有疑惑:不對阿,就算沒有網路,我還是可以在自己的電腦裡面寫 code 不是嗎?

這個說法沒錯,不過這邊想強調的是,做不到的事情是「版控」,而不是「開發」。就算已經開發好程式,因為沒有網路,所以沒辦法把寫好的程式「紀錄」進版控之中,也就是沒辦法「對遊戲下存檔點」的概念。

上面這段其實是筆者曾經的疑惑,特別記錄下來希望有相同疑惑的讀者能解惑。

還有一個問題是,集中式版控系統在專案越來越大的時候,由於網路傳輸頻寬有限,資料越多讀取速度越慢,這造成版控的效率會大幅的降低,到了後期上傳資料的時間或是取得紀錄(log)的過程差不多可以去泡一杯咖啡了。

集中式版控系統或許還有未提及的優缺點,不過一來這不是文章主要內容,再來筆者涉略不深怕寫多了會誤人子弟,就點到為止。

話不多說,來講 Git 吧。

# 分散式版控系統

# 介紹

分散式版控系統

所謂的分散式版控系統,意思是儲存庫可以直接建立在每個開發者的電腦中,每個人的電腦都會有完整的版控資訊,開發者不會直接連到遠端版控,而是先在地端做好版控後,再將資料上傳到遠端。

而且如同集中式版控系統一樣,協作開發會透過「遠端儲存庫」共用資料,將「版控資料」同步回自己的「地端儲存庫」後,再繼續開發。

Git 就是屬於分散式版控系統

# 優點

因為每個人的電腦都有儲存庫,代表版控不需要「遠端儲存庫」就可以進行。
也就是說,使用 Git 版控,不用設定遠端儲存庫,也能在離線狀態對專案作版控。

由於把遠端儲存庫與地端儲存庫拆分開來控制,在地端儲存庫的版控行為,並不會影響到大家共用的遠端儲存庫,不用擔心一時操作失誤,搞壞整個團隊的資料。

再來是「分散式管理系統」通常都有很好操作的「分支操作功能」以及「還原資料功能」,再加上這些功能在地端就能完成,少了網路傳輸時間,即使資料量再大,速度也慢不到哪裡去。 如果還是覺得太慢,可能是在提醒你,該換電腦了

# 缺點

講了一堆吹捧「分散式管理系統」的內容,其實他還是有缺點存在。

「分散式管理系統」最大的缺點,就是團隊版控過程沒辦法鎖定不同人存取個別檔案的權限,畢竟每個人在電腦中都有一個完整的儲存庫,沒辦法特別去設定每個開發者在自己電腦存取的資料。

「分散式管理系統」通常比「集中式管理系統」來得複雜,要在一個沒完全沒碰過「分散式管理系統」的團隊中導入這個技術,學習成本相較來得高。

此外,也因為複雜度高,如果團隊對於「分散式管理系統」的觀念不清楚,很可能因為觀念混淆而造成操作錯誤。

# 補充

# 在分散式版控系統需要用到「遠端儲存庫」的狀況

上述有特別強調,分散式管理系統可以在本機端直接完成版控,這樣的狀況下還會「遠端儲存庫」的原因,大致上有三點:

  1. 想在遠端備份程式:
    遠端儲存庫其實也是一種雲端備份空間,要避免地端資料遺失,備份到遠端儲存庫是一個不錯方式。

  2. 想分享自己的程式給他人看:
    如果讀者有聽過「open source」,開源程式的概念,它通常就是透過 GitHub 這個「遠端儲存庫」來跟社群分享程式。

  3. 團隊共同開發專案:
    這應該不用解釋了,就是因為 Git 很適合拿來團隊開發,才會讓大家趨之若鶩學習 Git。而使用 Git 團隊開發的方式,就是需要一個團隊共用的「遠端儲存庫」。

雖然列出了三項,不過概念都是要讓其他人 (或是其他裝置) 存取地端的資料,才需要用到遠端儲存庫。否則只需要地端儲存庫,就可已使用 Git。

# 總結

到這邊讀者們應該可以看得出來,雖然兩種主要的版控系統都有它的優缺點,但分散式管理系統的優點明顯多於缺點,而這些缺點其實也都有辦法克服。
這也是 Git 能成為版本控制的全球標準的原因之一。
(這浮誇的言論不是我說的,是 微軟官網 說的)

總結這篇文章的重點:

  1. 使用「複製貼上大法」來備份程式效率太差,所以需要版控系統協助。
  2. 版控系統分為「集中式版控系統」與「分散式版控系統」兩種。
  3. Git 屬於分散式版控系統,並且已經是世界主流。
  4. 分散式版控系統特性是能在地端版控。除非必要,否則不須建立遠端儲存庫。
  5. 只有需要讓他人 (或其他裝置) 存取本機的程式時,才需要建立「遠端儲存庫」。