Git 的多人協作


Posted by saffran on 2020-12-01

Git 要如何做到多人協作呢(讓大家共同開發一個 Git 的專案)?

在 Git 裡面,「被 Git 控制的一個專案」就稱為一個「repository」

因此,多人協作就是要「共享同一份 repository」

Git vs GitHub

Git 是一個「版本控制的程式」
GitHub 是一個「可以放 Git repository 的地方」,當然也還有其他更多的功能

GitHub--> 視覺化你的 repository

在 GitHub 中,README.md 檔案的內容 “預設” 就會顯示在頁面下方,
README.md 通常會寫一些:專案的介紹、使用操作說明等等

在出現 bug 時,用 GitHub 可以很方便的查看「這行程式碼是誰寫的、最後修改時間、為什麼要修改」,才能查出為什麼會有這個 bug

History

點擊 History,可以看到這個檔案過往的所有 commit 記錄和 commit message(為什麼要改)

(commit 就是“提交一個版本”的意思)

Blame

點擊 Blame,可以看到每一行程式碼「最後是被誰改的、是什麼時候改的」,當有問題時就知道要找誰去問了

把本地的 code 同步到 GitHub 上

可以想成是:「本地端的 repository」跟「GitHub 上的 repository」其實是同一個,但是需要自己“手動”去同步它們兩個

要如何把「我的電腦裡的 Git repository」放到 GitHub 上呢?

1. 在 GitHub 點擊右上角的 + 號,選擇 New repository

2. 我把 repository 取名為「git101_test」,按下 Create repository 之後,我的 repository 就在 GitHub 上面建好了(目前是一個空的 repository)

3. 看到的第一個畫面會是一個教學說明,那因為我在本地端的電腦上已經有 repository 了,因此就可以參考「…or push an existing repository from the command line」的教學

git remote add origin https://github.com/yuwensaf/git101_test.git
  • remote 就是「遠端」的意思,git remote add 代表「我要新增一個遠端的 repository」
  • 這個遠端 repository 的位置是 https://github.com/yuwensaf/git101_test.git (是 GitHub 提供的位置)
  • 這個遠端 repository 的名稱是 origin (是 GitHub 預設的名稱,也可以自己改叫其他名稱)
git push -u origin master
  • push 就是「把本地端的檔案推上去」
  • -u 這個參數代表 -set-upstream,意思就是:設定一個地方(我要把檔案推到那個地方),在這裡就是 origin 這個遠端的 repository
  • master 是「我要推送的本地分支」
  • 整句指令的意思是:我要把「本地端的 master 分支」push 到「origin 這個遠端 repository」裡面

4. 因此,就在 CLI 輸入這兩行指令

git remote add origin https://github.com/yuwensaf/git101_test.git
git push -u origin master

重新整理網頁,就可以看到我推上去的檔案了(在 master 分支上)

git remote

使用指令 git remote 可以查詢:
目前,本地端有 clone 下來多少個遠端 repository

例如:
目前只有一個遠端的 repository 叫做 origin

  • origin 是預設的名稱,可以自己改名

git remote -v

使用 git remote -v 可以看到詳細版的遠端 repository 資訊

例如:
從這裡可以看到,origin 其實就是 https://github.com/yuwensaf/git101_test.git 這個 repository

remote name 是什麼?

remote name 其實就是 repo 網址的代號,
不然每次都要打 git push http://clay.gao/helloworld.git master,打這麼長一串指令超累的。

git remote add 代號 遠端repo網址

使用指令 git remote add 代號 遠端repo網址,來幫這個「遠端repo網址」取一個「代號」

例如:

git remote add myHome http://clay.gao/myHome.git

這樣以後要 push 時就用 git push myHome 分支名稱 就可以了

為何會需要對同一份 repo 取不同的 remote name 呢?

remote name 基本上就是指定一個代號

我朋友名字太難念所以我都叫他小菜,但也有人叫他阿菜,有人叫他菜菜,但都是指涉到同一個人

remote name 也是這樣,因為遠端的 repo 網址太長所以你取一個代號,你要叫他 aa 也可以,叫他 bb 也可以

但重點是 aa 就代表原本那個網址,bb 也是,就是取個綽號而已

實務上的用途是:假設你的專案程式碼要放在多個地方,放在 GitHub 的 repo 網址你可以取個 remote name 叫做 github,而放在 GitLab 的 repo 網址你可以取個 remote name 叫做 gitlab,這樣就不會搞混了

像是如果你有很多親戚都叫小明,你就會以台東那個小明或是台北那個小明來做區分,幫他們取不同的名稱,代表不同的人

圖解說明

注意!

除非專案要放在不同的遠端資料庫,像是 GitHub、GitLab、Bitbucket 等等,不然通常一個遠端資料庫(remote repository)只會取一個 remote name,同一個遠端資料庫取不同 remote name 反而會搞混

git push

使用 git push 遠端repository名稱 本地分支名稱 可以把我在本地端最新修改好的檔案,再次推送到 GitHub 上

流程如下:

  1. 我在本地端修改了 code.js 檔案
  2. 在本地端新增一個 commit

    git commit -am 'modify code.js'
    
  3. 輸入指令 git push origin master,來把「本地端的 master 分支」push 到「origin 這個遠端 repository」

注意!一定要做「push」這個動作,本地端的檔案才會跟遠端同步

  1. 回到 GitHub 頁面重新整理後,就可以看到最新的 commit 了

推送「本地端的其他分支」到遠端 repository

例如:

  1. 我在本地端建立一條新的分支叫做 issue
    git branch issue
    
  2. 切換到 issue 分支
    git checkout issue
    
  3. 輸入指令 git push origin issue 就可以把「本地端的 issue 分支」push 到「遠端的 origin 數據庫」
    git push origin issue
    
  4. 在 GitHub 頁面上,就可以看到剛剛同步上去的 issue 分支了

git pull

假設我的同事在 GitHub 上做了修改,那我要怎麼把遠端最新的版本同步到本地端呢?

在 GitHub 直接修改檔案

GitHub 有提供「修改檔案」的功能

因為在 GitHub 上面也是一個 Git repository,因此檔案改完之後也要做 commit 的動作

  1. 進入檔案,點擊這個鉛筆 icon,就可以進入修改的頁面
  2. 修改完成後,只要按下 Commit changes,GitHub 就會自動幫我產生 commit 了

git pull origin master

輸入指令 git pull origin master,就可以把「遠端 origin 的 master 分支 」pull 到「本地端的 master 分支」

當 pull 遇到衝突時

  1. 我在本地端修改了 code.js 的第一行,改完後新增一個 commit
    git commit -am 'modify first line'
    
  2. 同事也在 GitHub 上修改了 code.js 的第一行,改完後在 GitHub 新增一個 commit
  3. 這時,我在本地端輸入指令 git pull origin master,就會出現衝突「Merge conflict in code.js」
    git status 可以看到
    Unmerged paths:
    (use "git add <file>..." to mark resolution)
     both modified:   code.js
    
  4. 因此,就把 code.js 打開來看,自己手動決定要保留的內容,儲存檔案後就可以新增一個 commit
    git commit -am 'update code.js first line'
    
  5. 然後就可以從本地端 push 回去到遠端 repository,遠端的 repository 就會被同步更新了
    git push origin master
    

git clone

假設今天我在逛 GitHub 時,看到一個 repository 叫做「中文文案排版指北」很不錯,要怎麼把它抓下來到我的電腦裡呢?

方法一:把檔案整個下載下來

點擊右邊的綠色按鈕「Clone or download」的「Download ZIP」,就可以把檔案整個下載下來了

方法二:使用指令 git clone

  1. 把這個 HTTPS 網址給複製起來
  2. 在我的 CLI 上,輸入指令 git clone https://github.com/sparanoid/chinese-copywriting-guidelines.git
    git clone 後面就是接我剛剛複製的網址)
    這樣就可以把這個 GitHub 上的 repository 複製一份到我的電腦裡了

想修改但是沒有權限

  1. 我把「中文文案排版指北」複製到我的電腦上後,我打開它的 README.md 檔案,在第一行加上一些字
  2. 存檔之後,在本地端新增一個 commit(因為現在都是在我本地端的 repository,所以在本地 commit 沒問題)
  3. 但是,當我要把它 push 到遠端時,輸入指令 git push origin master 就會看到錯誤訊息,原因是:
    因為這是別人的 repository,我沒有權限可以改

Fork 到自己的帳號底下

如果我想要做一個自己的版本,可以這麼做:

  1. 在別人的 repository 右上角點擊 Fork,
  2. Fork 完成之後,就可以看到:在我的帳號底下,有了這個「中文文案排版指北」的 repository
    同樣地,把 HTTPS 網址複製起來
  3. 在我的 CLI 上,輸入指令 git clone https://github.com/yuwensaf/chinese-copywriting-guidelines.git
    git clone 後面就是接我剛剛複製的網址)
    這樣就可以把這個 GitHub 上的 repository 複製一份到我的電腦裡了
  4. 這時,我修改了這個 repository 裡面的檔案,新增一個 commit
    git commit -am 'edit the first line'
    
  5. 這一次,我就可以成功 push 到遠端去了
    git push origin master
    
    原因是:這個 repository 是在我的帳號底下(是我的 repository)

  1. 在本地端新增一條分支叫做「new-button」
  2. 切換到 new-button 分支,新增一個檔案叫做 redbutton 之後,新增一個 commit
    git commit -am 'add new file'
    
  3. 把本地端的 new-button 分支 push 到 GitHub 上
    git push origin new-button
    
    # pull request 合併分支
    ## 注意!
    發完 PR 之後,如果你又想修改一些東西,其實你可以自己在電腦上改完、commit 之後再把分支 push 上去一次即可,GitHub 上的 PR 就會自動更新了,你什麼都不用做,更不用把 PR 關掉再發一次新的 PR。因為 PR 的主體是「branch」,所以只要 branch 更新了,PR 的內容自然也會一起更新。
    ## pull request 其實就是「在 GitHub 的介面上做 “merge 分支” 的動作」
    如果是在本地端 merge(使用指令 git merge new-button),我沒辦法看到兩個分支之間的檔案差異,是比較不方便的

因此,大家通常都會使用 GitHub 的 pull request 這個功能來 merge 分支


這時,可以看到這個按鈕「Compare & pull request」,意思就是:

這個 request 是想要把「new-button 分支」合併到 master 上

輸入完標題、敘述後,點擊「Create pull request」

然後,就可以先檢查一些內容(檔案差異等等),確定沒問題之後,
點擊「Merge pull request」
點擊「Confirm merge」

成功把 new-button 分支 merge 到 master 分支後,就可以把 new-button 分支刪除掉了

這時,master 分支上,就擁有 new-button 分支的內容了


如果我想要貢獻別人的專案,流程基本上是這樣:

  1. 把別人的專案 Fork 一份 repository 到自己的帳號底下
  2. Fork 完之後,開一條新的分支,改完檔案後,把新的分支 push 到自己的遠端 repository 裡面
  3. 這時,就可以發起一個 pull request,要求把「自己的 branch」合併到「別人的 repository 的 branch」

GitHub Flow 工程師之間的協作

在 push 會遇到的問題

  1. 我在 GitHub 上面的 repository 修改了一些檔案
  2. 我又在本地的 repository 修改了檔案後,想要 push 到遠端去,但是輸入指令 git push origin master 後,卻出現錯誤訊息
    原因是:遠端已經有一些改變是本地端沒有的,所以本地端沒辦法 push。要先把遠端的最新版本 pull 下來才行。

因此:

  1. 我先使用 git pull origin master,把遠端的最新版本抓下來到本地端,讓本地端先跟遠端同步

GitHub flow

GitHub flow 是一個 work flow,建議你「在一個專案中,要怎麼管理你的 branch」,流程大概是這樣:

  • 要新增一個功能,就新增一條 branch > 修改檔案 > add commits > open a pull request (在 GitHub 上面把分支合併回去)> 同事們就可以在 GitHub 上,對你的 code 進行 code review > merge 到 master(這時就可以把這條 branch 刪掉了)

實際跑一次 GitHub flow 流程:

  1. 在本地端新增一條 branch 叫做 bug-fix,然後切換到 bug-fix 分支
  2. 在 bug-fix 分支修改 code.js 檔案後,新增一個 commit
    git commit -am 'add new code'
    
  3. 把 bug-fix 分支 push 到遠端去
    git push origin bug-fix
    
  4. 在 GitHub 就會偵測到「有一條新的 branch」,這時就可以按下「Compare & pull request」
    也可以在「Pull requests」頁籤,點擊「New pull request」
  5. 通過大家的 code review 之後,就可以 Confirm merge(merge 到 master)
  6. 在 GitHub 把 bug-fix 分支刪掉
  7. 在本地端回到 master 分支,輸入指令 git pull origin master,把遠端的 master 同步到本地端
  8. 把本地端的 bug-fix 分支刪掉

這樣就是一個完整的 GitHub flow 了!


#Git #Github







Related Posts

[08] JavaScript 入門 - 模組、this

[08] JavaScript 入門 - 模組、this

Python Table Manners - 管理繁瑣任務

Python Table Manners - 管理繁瑣任務

Day00 Elements of Clojure 書摘&心得

Day00 Elements of Clojure 書摘&心得


Comments