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 Repository

  • git 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 master

  • git 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 branch

  • git 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.

步驟整理:

  1. git fetch

  2. git checkout master

  3. git merge master origin/master

  4. 更改好合併衝突

  5. git merge master origin/master (須先add)
    git add chili-recipe.txt

  6. git commit chili-recipe.txt (不能只commit部分,要commit整體)
    git commit

  7. git 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版)才可以,但lsdir都能夠顯示檔案清單

results matching ""

    No results matching ""