2. 搞懂 Push、Pull、Fetch 與 Clone
封面那裏我有提到,Git最最大的用處就是讓我們創建分支,一條分支當實驗用,另一條分支當正式開發用。那實際開發時,我們到底是怎麼把程式碼在「本地電腦」與「雲端 GitHub」之間搬運的呢?
最直覺的理解方式,就是把這整個過程看作是一套「物流大師的拉貨與送貨系統」。
1. 本地(Local)與 遠端(Remote)
在開始搬運前,我們要先劃分兩個世界:
- 本地(Local): 就是你的電腦,正在用 VS Code 寫扣的地方。
- 遠端(Remote): 遠在天邊的 GitHub 伺服器,用來保存團隊共同資產的地方。
這兩個世界各有各的 Git 紀錄。而接下來的四個動作,就是連接這兩個世界的橋梁。
2. Push、Pull、Fetch、Clone
Push
- 白話文: 「老闆,我貨包好了,現在發車送去總倉!」
- 幹嘛用: 當你在本地寫完程式、做好 Commit(紀錄點)後,這些變化依然只在你的電腦裡。你需要透過 Push,把本地的新 Commit 「推」上 GitHub。這樣一來,雲端上才會更新你的最新進度,協同開發的夥伴也才看得到。
Pull
- 白話文: 「聽說總倉有新貨?立刻載回來並直接上架到我的店面!」
- 幹嘛用: 當團隊裡的其他工程師 Push 了他們寫好的新功能到 GitHub,此時你本地的程式碼就落後了。你需要透過 Pull,把 GitHub 上別人寫好的新進度「拉」回你的電腦,而且 Git 會非常聰明地自動幫你合併(Merge)到你目前的檔案裡。
Fetch
- 白話文: 「聽說總倉有新進度?我先拿個出貨單看看改了什麼,但我店面的貨先維持原狀。」
- 幹嘛用: Fetch 與 Pull 非常像,但少了一個「自動合併」的步驟。 執行 Fetch 時,Git 只會把雲端的最新狀態同步到你本地的「遠端追蹤分支」紀錄裡,但完全不會動到你目前正在寫的任何檔案。適合用在你「想先確認別人改了什麼,確認沒問題後再自己手動合併」的場景。
💡 大公式:
Pull = Fetch + Merge(合併)
Clone
- 白話文: 「這家店的加盟總部蓋得太好了,我要複製一模一樣的整座倉庫到我家隔壁!」
- 幹嘛用: 通常是用在你剛加入一個新專案,或者在 GitHub 上看到別人的開源專案很讚時。你本地目前「什麼都沒有」,這時只要輸入
git clone [網址],Git 就會把遠端儲存庫的程式碼、歷史紀錄、所有分支,原封不動、徹徹底底地完整下載一份到你的電腦裡。
3. 總表
| 動作 | 方向 | 什麼時候會用到? | 對本地檔案的影響 |
| Clone | 雲端⮕本地 | 第一次要下載整個專案時。 | 建立全新資料夾與所有歷史。 |
| Push | 本地⮕雲端 | 寫完一個階段,想備份或分享進度時。 | 無,只會更新雲端。 |
| Pull | 雲端 ⮕本地 | 開始寫程式前,確保自己拿到團隊最新進度。 | 會,直接改寫你目前的檔案。 |
| Fetch | 雲端 ⮕本地 | 想知道雲端有沒有更新,但現在不想動到本地檔案。 | 不會動到你正在寫的檔案。 |
4. 實戰push !
第一章的時候我們有建立了一個專案,裡面包含index.html,並將其推送上GitHub,這些動作稱為Initialization 初始化。
那現在正式進入開發階段後,又該如何操作呢?
1. 修改檔案(例如新增一行字):
我們透過指令來修改index.html這個檔案(當然你也可以從VScode中開啟並修改)。
echo "<p>Update: Adding some new features...</p>" >> index.html
Code language: HTML, XML (xml)
2. 重複以下三步驟:
git add .
git commit -m "Update index.html with new paragraph"
git push
Code language: JavaScript (javascript)
git add .表示把當前資料夾的所有檔案一次裝箱git commit -m-m後面的雙引號裡,請務必寫下「這次做了什麼更改」的白話文(通常會是: 動詞 + 名詞 e.g. 新增 首頁),給這次裝箱的貨物貼個標籤。git push把貨送上 GitHub !
以後日常開發,你只需要瘋狂重複這三行指令,你的雲端進度就會永遠維持最新狀態。
5. 實戰 Clone!
我們成功把專案推上 GitHub 後。現在,請在你的電腦上開一個全新、空空如也的資料夾,我們來模擬「在另一台電腦上下載專案」的情境。
當你到一家新公司上工,或是想把 GitHub 上別人的開源專案整包抓下來時,這是你「第一個會輸入的指令」。
進入全新的空資料夾後,請去你的 GitHub 複製上一章建立的專案網址(https://github.com/你的帳號/my-project.git),然後再終端機輸入:
git clone https://github.com/你的帳號/my-project.git
Code language: PHP (php)
接著進入資料夾並輸出檔案看看~
cd my-project
ls -la
你會看到資料夾裡不只有
index.html,連隱藏的.git資料夾都幫你準備好了!這代表clone不只幫你下載檔案,連遠端地址(origin)和所有的歷史紀錄都一併複製過來了,你不需要再重新輸入git init。
6. 實戰 fetch !
為了模擬「別人在他那裡改了程式碼」的情境,我們現在做個小實驗:
- 請打開你的 GitHub 網頁,點進去
index.html。 - 點擊右上角的小鉛筆編輯它,在裡面隨便加上一行字:
<h2>This line is edited from GitHub website!</h2>。 - 點擊 Commit changes… 儲存。
此時,雲端的進度已經領先你本地的電腦了。接下來我們用 fetch 來打探敵情:
git fetch
這時終端機會跳出一些進度條,代表它已經去雲端「抓取最新的紀錄」下來了,接著用 VS Code 打開本地的 index.html,會發現剛剛在網頁上改的那行字「還沒有出現」!
fetch 的本質: 它只會更新你本地電腦裡的「遠端分支紀錄」(例如 upstream
/main),讓你知道雲端有新東西,但不會擅自修改你目前的實體檔案。
7. 實戰 pull !
如果你看完 fetch 的項目,確認雲端的修改沒問題,想要把正式版本的新程式碼「合進來」你目前的檔案,這時就要用 pull。
git pull
終端機會顯示 Fast-forward 以及有哪些檔案被修改了。
這時候回頭去看你的本地 index.html,你會發現網頁上改的那行 <h2> 已經完美出現在你的程式碼裡了!
其實日常開發中,如果你百分之百確定雲端的程式碼很乾淨,可以直接輸入
git pull,它會自動幫你做完fetch + merge(合併)。
Daily Flow
學會了這套組合拳後,以下是未來的工程師日常基本素養:
- 每天早上開工第一件事: 先輸入
git pull,把團隊昨天深夜推上雲端的最新進度拉下來,避免自己寫在舊的基底上。 - 寫完一個功能後: 先
git add .⮕git commit⮕ 最後git push送上雲端。
熟悉後就不是什麼難題啦!
