昨天,我們先把版本留在自己的電腦裡。
工作目錄
↓
暫存區
↓
本地儲存庫
但如果想把成果分享給別人看,或是四個人要一起完成同一個專案,總不能每個人都只守著自己電腦裡的版本對吧?
但真的開始跟隊友一起用 Git 之後,我才發現:
自己存版本是一回事,開始進到大家共同的協作流程又是另一回事。
第一次協作的時候,我真的超級緊張!!!
改壞自己的東西我自己修就好。
真的不想把別人的也一起弄壞啊~~
這時候,就需要把本機的版本放到一個大家都能存取的遠端儲存庫(Remote Repository)。
如果繼續用遊戲來想,就像大家平常各自在家解任務,但還需要一個共同的「公會據點」,讓所有人可以把進度集中在一起、互相查看和協作。
提供遠端 Git 儲存庫的平台不只有 GitHub,今天會以實務上很常見的 GitHub 為例。

這兩個名字我一開始很容易直接混成同一個東西。
其實它們負責的是不同事情:
Git
→ 版本控制工具
→ 負責追蹤、管理版本歷史
GitHub
→ 遠端 Git 儲存庫與協作平台
→ 讓團隊可以共享版本、看修改、討論與整合程式碼
也就是說,沒有 GitHub,Git 一樣可以在自己的電腦裡做版本控制。
如果 Git 是我自己在家整理任務進度的工具,那 GitHub 就比較像大家共同使用的公會據點。
本機版本要怎麼送過去、隊友更新的進度又怎麼拿回自己的電腦,後面就會慢慢看到 git push 和 git pull 在做什麼。
不過在真的把任務成果送出去以前,還有一個很重要的概念要先看:
分支(Branch)。
多人一起開發時,如果所有人都直接在同一條版本線上改東西,很快就會變得很難管理。
如果用遊戲來想,我覺得分支(Branch)很像:
從主線任務旁邊開出一條支線。
例如原本有一條共同的 dev,其中一個功能可以從某個 Commit 分出去,先走自己的開發路線:
↑ 較新的 Commit
feature/chat ● F2
│
● F1
/
dev ● D2
│
● D1
↓ 較舊的 Commit
更精準地說,feature/chat 會從 dev 某一個 Commit 分出去,之後在自己的分支(Branch)上繼續累積新的 Commit。
所以我可以先在自己的分支(Branch)上完成聊天功能,不需要把還沒完成的修改直接放進團隊共同的 dev。
等這條支線任務做好,下一步就是把成果送到大家共同的 GitHub。
git push:把自己的任務成果送到 GitHub假設我現在在自己電腦上的:
feature/chat
已經完成幾個 Commit。
但這些版本目前還只存在自己的電腦裡。
要把這條分支(Branch)的進度送到 GitHub,就會用到:
git push
把本地的版本推送到 GitHub 上的遠端儲存庫。
如果繼續用剛剛的遊戲比喻,就像:
我和朋友平常各自在家解自己的支線任務,現在把完成的進度送到大家共同的公會據點。
不過在真的推上去以前,還有一件事情很重要。
.gitignore:有些東西不是不想上傳,是根本不能進 Git準備把分支(Branch)推到 GitHub 以前,有一件事真的很重要:
不是專案資料夾裡的每個檔案,都適合被 Git 追蹤。
尤其是像:
.env
API Key(API 金鑰)
Access Token(存取權杖)
Database Password(資料庫密碼)
Private Key(私密金鑰)
這些敏感資訊一旦被 Commit,就可能留進 Git 的版本歷史。
如果後面又 Push(推送)到遠端儲存庫,甚至可能直接變成資安問題。
像 API Key(API 金鑰)外洩後,別人可能拿它呼叫你的服務、消耗額度,甚至存取原本不該碰到的資源。
所以專案裡通常會使用:
.gitignore
告訴 Git:
符合這些規則的檔案,不要加入版本追蹤。
像存放環境變數的 .env,就很常被加入 .gitignore。
不過 .gitignore 主要是避免尚未被 Git 追蹤的檔案被加入版本控制。
如果某個敏感檔案早就已經被 Git 追蹤或 Commit 過,後來才把它加進 .gitignore,並不會自動停止追蹤,也不會把版本歷史裡的敏感資訊清掉。
所以更重要的是:
從一開始就不要讓這些敏感檔案被 Commit 進版本歷史。
有些東西不是「不需要上傳」。
是真的不能不小心傳上去。
好,現在我的支線任務終於做好,也已經透過 git push 送到 GitHub 了。
但這還不代表可以直接大喊:
「支線任務完成!直接接回主線!」
畢竟這不是只有我一個人的遊戲。
在正式把自己的修改接回團隊共同的分支(Branch)以前,通常還會先開一個:
拉取請求(Pull Request,PR)。
如果繼續用公會的比喻,它很像是在說:
「我的支線任務解完了!大家幫我看看,這份成果可以接回主線了嗎?」
在 GitHub 的 PR 裡,隊友可以直接看到這次改了哪些程式碼,也可以留言一起討論。
這就是 審查(Review) 的一部分。
例如:
這裡是不是漏掉一個狀況?
這段邏輯為什麼這樣處理?
這裡要不要再調整一下?
就像大家一起驗收:
這個任務到底解得怎麼樣?有沒有哪裡還要補?
確認修改沒問題後,有審查權限的隊友就可以對 PR 提交 Approve(核准)。
符合團隊的合併條件後,就能在 GitHub 上執行:
合併(Merge)。
把原本自己出去解的支線任務,正式接回目標分支(Branch)。
整段流程可以先想成:
自己的電腦
支線任務:feature/chat
│
│ git push
▼
GitHub 公會據點
feature/chat
│
▼
Pull Request(PR,拉取請求)
│
├─ Review(審查)
├─ 留言/討論
└─ Approve(核准)
│
▼
Merge(合併)
│
▼
共同的主線任務
dev
剛剛的 feature/chat 已經在 GitHub 上成功 Merge(合併)回 dev。
現在公會裡的主線任務已經更新了。
但我自己電腦裡的 dev,還不一定跟著自動更新。
這時候就可以切回 dev,再使用:
git pull
把遠端最新的進度同步回自己的本機。
如果繼續用遊戲來想:
公會的主線劇情已經往前推進了,我也要把最新進度同步回自己的遊戲裡。
整個流程就會變成:
各自在本機解支線任務
↓
git push
↓
把成果送到 GitHub 公會
↓
PR(拉取請求)
↓
Review(審查)/討論
↓
Approve(核准)
↓
Merge(合併)
↓
支線成果接回共同主線
↓
git pull
↓
把最新主線同步回自己的電腦
到這裡,是不是覺得 Git 協作沒那麼可怕了呀!
把前面的流程串起來看,其實大家不是一起擠在同一條版本線上亂改,而是各自在自己的分支(Branch)上解支線任務,再把成果送回團隊共同的主線進度。
而且就算中間真的改錯了,只要版本有好好留下紀錄,也還有機會找到前面的狀態、回頭處理,而不是一改壞就整個救不回來。
但知道「怎麼協作」之後,新的問題也跟著出現了:
每個人到底要從哪一條分支(Branch)開?做完之後,又應該合回哪裡?
有分支(Branch),不代表大家自然就會用同一套方式合作。
如果每個人都照自己的習慣走,就算每一個 Git 指令都下對了,整個專案還是可能亂成一團。
所以多人協作除了會用 Git,還需要:
一套大家共同遵守的分支規則。
下一篇,就來看其中一套經典的分支模型:
Git Flow(Git 分支工作流程)。