前言
承接上一篇文章 版本控制 - 基本 Git 指令,我們了解到,我們可以利用 Git 實現自己電腦上的版本控制。當未來進入職場時,我們會需要多人協作,屆時就需要一個大平台來管理所有人的檔案跟資料。這種多人協作下的版本控制,我們利用 GitHub 這個網站來實現。
本文會提到的內容如下
- branch 的概念
- branch 的操作方式 (指令介紹)
- conflict 發生衝突,如何處理 (衝突處理)
- GitHub 的操作方式 (指令介紹)
- GitHub 的應用範例 (以部落格為例)
- 特殊狀況處理
先來聊聊 branch 概念
我們為什麼需要 branch ? branch 是什麼?
- 想像你是一個甜甜圈老闆,你的巧克力甜甜圈大受好評,店裡人滿為患。某天你看著你的巧克力配方,突然靈機一動想到了一個改良的點子,也許能夠增添更多商機,說不定還可以熱銷到全世界。興奮的你馬上在舊的配方上面加上新的 idea。改良到一半的時候,有一間美食集團的大老闆來找你談生意,希望以 3000 萬買下你的巧克力配方。你猶豫了...,因為你已經在舊配方上寫下你新的 idea,你不想讓別人知道你新的 idea 內容,可是想要賺這 3000 萬你就必須把這份配方給他(假設這份配方非常複雜無法複製第二份)。你心裡想著,要是我當初的 idea 是另外寫在別的地方就好了。
branch 的概念就是,不管你要做任何事情,都不要去改動原始的東西,而是先將原始資料備份,
並在備份的檔案上來操作,確保原始的資料是完整的。
- 換到程式的角度來看,假設你們公司去年提供了一個
完整版
軟體給客戶使用。今年度開始要將完整版
改良成新版本
。你開始在完整版
上面改良,現階段完成了完整版 + 50%新版
。某天客戶突然告訴你發現程式有 bug 要修,你如果在完整版 + 50%新版
修正完 bug 並提供給客戶,客戶就會看到一個 50% 的新版內容。因為 50% 的新內容不能提供給客戶看,所以你要把所有新版本都拿掉,回復成完整版
後,再去修正 bug,你的新版本就通通白做啦。
簡單的概念: 要做任何事情,就到新的 branch,等到完成後,再合併回 master。
* 有了 branch 之後,你會有一條原始資料的主要 branch,他叫做 master。
* 要開發新版本,就會新增一條開發新版本的 branch,
* 要修正 bug,就會新增一條修正 bug 的 branch。
* 一但這條 branch 確認完成後,才可以把完成的資料,放回去 master 這條原始的 branch
實際上 branch 的操作
如果沒有新建新的 branch,系統預設的 branch 就叫做
master
git branch <name>
: 新增一條新的 branch
git branch -v
:查看目前有哪些 branch,以及告訴你目前在哪一條 branch
git branch -d <name>
:刪除 branch,請務必確認這條 branch 的資料已經合併回 master。
git checkout <name>
:切換到別的 branch
注意!若是目前的 branch 有檔案在完成改動後尚未 commit,系統會發出提醒
- 補充:
git checkout -b <name>
:新增一條新的 branch 並直接切換過去
git merge <name>
:合併分枝
- 把別的 branch 合併進來現在的 branch
- 先
git checkout master
切換到 master 這條主要的 branch - 在執行
git merge new-feature
將 new-feature 合併進來現在這條 master
- 先
由於 merge 到底是誰會合併誰,常常容易搞混,可以記住一個概念:
* 下指令的人是 Boss,Boss 才會下 merge 指令
* 屬下才會交報告給 Boss,所以一定是屬下的資料給 Boss
* 也就是說,我在 Boss 這條 branch 下 merge 我就是 Boss,被我呼叫到的 branch 要把資料合併給我。
合併時發生衝突怎麼辦
回顧上一篇文章 版本控制 - 基本 Git 指令提到的故事
睏寶正在編輯 project_sleep 這個檔案,正好海盜船長也在自己的電腦修正同一個檔案,睏寶先編輯完後上傳到資料夾,海盜船長比較晚完成,但也把完成的檔案上傳上來,結果睏寶編輯好的檔案就被 覆蓋 掉了。
在 merge
的時候,若新檔案與就檔案有改動到相同的地方,就會發生衝突,我們就叫做 conflict
。此時需要 手動
將衝突的部分修改完成。才能完成 merge 的動作。
(此部分的操作畫面待補)
終於來到了 GitHub
我們在自己電腦對於資料夾進行 版本控制
後,需要在 GitHub 上面開一個 Repository
,並且將這個 Repository 與我們電腦的資料夾做連動。完成後
我們就可以看看 GitHub 相關的操作指令囉:
push
:推到 repository 上面
- 把自己電腦上完成的東西,推到 GitHub 網站上。
- 範例
git push origin new-feature
:將本機 new-feature 這條 branch,推到 GitHub 遠端。- 若不曉得
origin
是什麼,可以用指令git remote -v
來查看 origin 指的是哪裡
- 若不曉得
- 範例
pull
:從 repository 拉下來
- 把 GitHub 上面的資料,同步到自己的電腦上。
- 用法
git pull origin master
將 GitHub 上 master 的資料同步到自己電腦 - 用法
git pull <clone url> master
將別人的 Repository 同步到自己的電腦的master
- 用法
clone
:把 repository 的資料下載到自己電腦
- 將 gitHub 資料下載到本地
- 若是用
clone
把 repository 資料下來自己的電腦,可以跳過將 Repository 與我們電腦的資料夾做連動的步驟,因為 clone 到自己電腦的資料夾,會直接與 GitHub 連動。
若是 clone 別人的 repository,是無權可以修改的
fork
:把別人的 repository 複製一份成為自己的 repository
- 有權力編輯自己的那份 repository
我們來舉個實際例子吧
假設我在 GitHub 上建立了一個專門放置部落格文章的 Repository,我該怎麼操作來把文章更新至 GitHub 呢?
- 撰寫新的文章前,先開一條新的 branch,並切換到那條新的 branch 上面
- 接著就可以開開心心的撰寫自己的文章
- 完成之後可以利用
git add .
把檔案加入版本控制,並用git status
來確認是否成功加入
- 確認我們的文章有加入版本控制後,我們就可以
commit
成新的版本啦
在電腦上建立好版本後,就可以準備把他更新到 GitHub 上面囉,還記得要用什麼指令嗎?
- 沒錯,就是
push
- 沒錯,就是
這時候打開 GitHub 可以看到我們
push
上來的blog
這條新的 branch- 在 GitHub 上面查看 branch
- 在 GitHub 上面查看 branch
- 點選
new pull request
後,我們會發送一個請求,讓自己的 branch 可以合併到 master 上面
- 這邊是請求核准的介面,用來決定是否要將 branch 合併進來
- 這個時候我們就完成將文章更新至 GitHub 的動作了!
- 確認合併後可以決定要不要把 blog 這條 branch 刪掉
- 更新至 GitHub 之後,我們要確保本機的 master 與 GitHub 上面同步
- 所以我們要先切換到
master
後,把 GitHub 上的資料pull
下來
- 所以我們要先切換到
- 此時本機的
master
也同步完成了,就可以將撰寫文章的blog
這條 branch 刪掉囉
以上就是一個完整的示範範例,我要做事情了!先新建一條新的
branch
並切換到新的branch
上面,完成我要做的事情後,commit
成新的版本。在用push
指令更新至 GitHub 上面,在網站上面把它merge
到master
完成更新。在把 GitHub 的資料同步到自己電腦的master
,最後把自己做事情的branch
刪掉!
Q & A 時間
commit 版本命名,名字取錯了可以改嗎?
git commit -amend
可以更改 commit 的名稱
注意一但 push 到 GitHub 上後,盡量不要去改還有個東西忘記改了,可以取消 commit 嗎?
git reset HEAD^
- HEAD 指的是最新的版本,^指的是上一個,也就是回到最新版的上一個的意思
我把東西弄壞了,可以回復上一次版本嗎?
git checkout --<file>
把某個檔案復原
git checkout -- .
把全部檔案復原
- 我可以換 branch 名稱嗎?
先 checkout 到要改名的 branch,再用git branch -m <名稱>
來改名
- 我可以拉下遠端的 branch 嗎?
git checkout <branch名稱>
可以直接拉下遠端的 branch
後記
git 是一個版本控制的程式,而 GitHub 就像一個雲端的倉庫,讓我們可以存放版本控制的檔案。雖然 GitHub 網站有實體的操作介面可以來點選。不過電腦與網站間的檔案交換都得靠 Command Line 來完成,還是需要不少時間來習慣。