gi## 前言
雖然官方已經有了說明手冊,但它主要是在講解概念,並沒有教學如何在Git(或終端機)上操作,由於筆者所用的Heroku(雲端運算平台)也是使用Git版本控制系統,因此打算從終端機打指令下手,真正瞭解如何實作。
什麼是GitHub?
GitHub:線上Repository託管平臺
能夠貢獻(Contribute)自己的內容
許多(注意:並非全部)都是開源的,代表可以自行修改成想要用的
GitHub鼓勵大家託管公開的Repository,並藉由託管私人的Repository收費
幫我記住使用者名稱和密碼
有三種方法
Repository若使用SSH,則必須用SSH認證而非使用者名稱和密碼,因為較複雜這邊省略
使用GitHub Desktop客戶端程式
在終端機內輸入
git config --global credential.helper wincred,會記住憑證
使Repository保持同步
要先將內容staged跟commit才能提交到GitHub上
上圖GitHub那並沒有畫Working directory跟Staging area,雖然它們兩者實際存在於伺服器上,但並不能直接存取,因此省略
有別於一般的雲端託管版本服務不同,使用GitHub需選擇兩個版本,When(時間) and How(方式) to sync?
雖然可以直接Clone下來(GitHub→本機端),但不能直接Clone過去(本機端→GitHub),因此需要先新增一個空的Repository再Push
遠端代碼庫(Remote Repository)
目的:在兩個Repository間同步數據
通常不會同步一個commit,而是指定一個Branch,因為一個一個commit傳效率太低
由於Master的Tip能觸及全部的commit,因此所有的分支都會出現(註:承接上次的檔案)
GitHub會由Tip向前追蹤(e53→fd2→a3b)
由於a3b已經存在於GitHub的伺服器,不須重新上傳,因此上圖不需要選a3b
練習新增Repository
因為我們本機端已經有檔案與commit,因此上圖的「Initialize this repository with a README」不必勾選。
註:勾選後會自動產生一個commit(請注意,Git無法Clone沒有Git的Repository),並新增一個空白的README檔案
git remote// 查看目前所有的Remote Repositorygit remote add <repository_name> <url>// 新增一個Remote Repository可以取任何name,name是用來代稱Remote Repository
但如果只有一個Remote Repository,name通常會使用origin
url建議採用https,若要採用SSH可參考這篇
為了確認URL無誤,可以輸入下面這個語法驗證:
git remote -v// v:verbose(詳細的),會輸出更詳細的訊息git push <repository_name> <branch_name>// 傳送
git pull <repository_name> <branch_name>// 拉回
註:上圖問的是只在對Repository進行Push與Pull動作後的狀態,因此本機端與遠端應有同樣的檔案,因此選第三個Neither
概念圖
Fork Repository
| Before |
After (Using Fork) |
|---|---|
目的:取代掉繁雜的過程(先Clone到本機,再Push到新的Repository)
GitHub會記錄有多少人Fork,而所有的Fork都會連結到原作,除了能感謝原作的貢獻,並且能向原Repository提出更改建議。
注意右上角,Fork是GitHub發明,專指在GitHub上操作的行為,並不適用於本機端
而Branch代表分支,但右上角的檔案並非線性發展,因此不是Branch
Clone代表複製,無論是Remote Repository→Local或Local→Local都是Clone
練習:Fork Recipe Repository(範例)
- clone下來的repository會自動新增一個名為「Origin」的Remote Repository,不用自己手動新增
- 可於Setting→Collaborators新增協作者
註:我們所做的推送並不會影響到原作的Repository
協作引發的衝突(Conflict Collaboration)
時機:(個人)在多台裝置上編輯同個專案,(眾人)與他人合作時
此時會合併引發衝突的兩個commit
練習:更改Chili-recipe
| 本機端 |
模擬Sarah的版本 |
|---|---|
更新Remote Branch的本地副本
上圖代表在本機端新增一個commit並指向它,會發現本機副本(origin/master)跟GitHub上的master並沒有更動
當有一個Remote Repository時,Git會將所有的Remote Branch保存一個副本到本機端,此副本會保存最後一次push/pull的Branch狀態
本地副本名為<remote_repository_name>/<local_branch_name>
如:origin/master本機副本實質上也是一個branch
上圖代表若將local push到GitHub上,本機副本的標籤會跟著移動
但若在本機跟GitHub上都新增一個不同commit(a72,5b3),pull下來可能會發生衝突,此時可以採用git fetch在本機端新增一個本地副本(5b3),避免發生衝突或覆蓋掉本機端的commit(a72)
→有點類似新增一個分支,並把GitHub上新增的內容丟進去
git fetch// 新增/取得一個本地副本
此時可以合併抓下來的本地副本(5b3)跟原本本機的master(a72)
此過程可以簡化成
git pull origin mastergit pull = git fetch + git merge // 縮寫
git pull origin master = git fetch origin + git merge master origin/master // 完整git branch-a// 能顯示本機+遠端的branch
特別注意這道錯了好多次的題目!
git status// master 相對於 local copy 的狀態
合併更改
由於fetch下來的origin/master跟本機的master內容有不同,因此輸入git status後會提示diverged
$ git status
On branch master
Your branch and 'origin/master' have diverged(分歧), and have 1 and 1 different commit each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working directory clean
git checkout master// 先切換到master branchgit merge master origin/master// 合併他們
注意:此時會出現合併衝突,因此需要更改檔案來解決
$ git merge master origin/master
Auto-merging chili-recipe.txt
CONFLICT (content): Merge conflict in chili-recipe.txt
Automatic merge failed; fix conflicts and then commit the result.
注意:更改好衝突檔案(chili-recipe.txt)後,記得要先add和commit,不可以直接merge,否則會出現以下錯誤:
$ git merge master origin/master
error: merge is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm <file>'
hint: as appropriate to mark resolution and make a commit.
fatal: Exiting because of an unresolved conflict.
注意:合併時不能只commit部分(git commit chili-recipe.txt),需要commit整體(git commit)
$ git commit chili-recipe.txt
fatal: cannot do a partial commit during a merge.
步驟整理:
git fetchgit checkout mastergit merge master origin/master更改好合併衝突
git merge master origin/master(須先add)git add chili-recipe.txtgit commit chili-recipe.txt(不能只commit部分,要commit整體)git commitgit merge master origin/master
上面步驟可以簡化成git pull origin master
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
若出現上面的錯誤,代表目前master超前local copy兩個commit,因此需要更新(push上去)使本機跟GitHub上相符
git push origin master
其他
- Git Bash中沒有
cd..的指令(Windows版),需使用cd ../(Mac版)才可以,但ls跟dir都能夠顯示檔案清單