# Github 協作指南:Branch 與 Pull request
###### tags: `團隊` `協作` `GitHub`
- Github 有「遠端」與「本地」的概念:
- 「遠端」指的是已經被儲存在 Github 網站上的進度
- 「本地」指的是儲存於電腦中,尚未上傳至遠端的進度
- 分支 Branch
- 分支就像平行時空的概念,在 A 分支中做的事情,不會與 B 分支產生任何衝突
- 分支在建立的時候可以選擇其建立的基準點(base on)是來自於哪個分支,在建立的當下會以基準點的進度完整複製一份到新建立的分支上
- 透過合併 merge 則可以將 A 分支中的進度合併進 B 分支中
1. Clone repository
- 這步會將遠端上所有分支的最新進度都複製一份到本地中,並建立新資料夾
2. Current Branch
- 你在本地中正在開發的分支
- 每個人都應該要在自己的專屬分支上開發,開發完再合併
3. Choose a branch to merge into <branch name>
- 選擇一個分支,並將其合併至指定的分支
4. Commit 提交紀錄
- 本地的檔案只要有任何與上次提交紀錄(如果未提交過,就是與空白檔案相比)時相異的變動,git 就會自動記錄這些變動,並讓你將這些變動紀錄進提交紀錄中
5. Push 推送
- 將變動的檔案內容與提交紀錄更新至遠端
6. Fetch
- 將遠端上所有分支的變動複製一份回本地
7. Merge
- 將本地中的兩個分支合併
8. Pull
- 相當於 Fetch + Merge
9. Pull Request 合併請求(別與 8. 的 Pull 聯想)
- 要求遠端儲藏庫的擁有者確認是否允許合併已經被推送到遠端上的兩個分支的內容
---
前情提要:
簡單來說,[Amigo-TravelerMap](https://github.com/DahisC/Amigo-TravelerMap)在Github上是一個儲藏庫,裡面會是我們最終的完成品。在開啟儲藏庫的同時,裡面會自動生成一分支,稱為main。
我們將[Amigo-TravelerMap](https://github.com/DahisC/Amigo-TravelerMap) clone下來後,會連同main一起clone,這時我們在本地會有[Amigo-TravelerMap](https://github.com/DahisC/Amigo-TravelerMap) 儲藏庫及main分支。
我們在裡面開五個分支,分別存放組員們各自的code,merge後Pull request發出請求,經過組長檢核過後,確定與本體不衝突、不會覆蓋到其他人、不會改到別人的css,就會將分支中的code合併進本體中。
流程及主要指令如下圖示。了解詳情請見 步驟說明 ,實作請見 Step by Step
- 單字介紹:
fetch 獲取:將某個遠端主機的更新,全部取回本地。
clone 克隆:通常是從遠端主機克隆一個版本庫
branch 分支:用來暫存更新版本
merge 合併:將兩分支合併

### 事前準備
先在Github Desktop中Clone這支儲藏庫,並在這兒create一個自己名字的分支(branch)
[https://github.com/DahisC/branchtest](https://github.com/DahisC/branchtest)
## 步驟說明
備註:(括號)內是分支目前的程式碼
遠端的資料夾Amigo 目前擁有分支:main (安安)
本地無資料夾
遠端的資料夾Amigo 目前擁有分支:main (安安)
↓clone
本地出現資料夾Amigo,擁有分支:main (安安)
根據 main 分支創建 test 分支 (Create new branch test base on main)
↓
遠端的資料夾Amigo 目前擁有分支:main (安安)
本地的資料夾Amigo,擁有分支:main (安安), test (安安)
發布分支 Publish
↓
遠端的資料夾Amigo 目前擁有分支:main (安安), test (安安)
本地的資料夾Amigo,擁有分支:main (安安), test (安安)
在本地分支 test 上改動程式碼 由安安→你好
遠端的資料夾Amigo 目前擁有分支:main (安安), test (安安)
本地的資料夾Amigo,擁有分支:main (安安), test (你好)
提交並推送 commit + push
遠端的資料夾Amigo 目前擁有分支:main (安安), test (你好)
本地的資料夾Amigo,擁有分支:main (安安), test (你好)
發起 Pull Request 要求合併遠端資料夾中 test 分支的內容至遠端資料夾中的 main 分支
↓ 檢查中 reviewing
准許合併
↓
遠端的資料夾Amigo 目前擁有分支:main (你好), test (你好)
本地的資料夾Amigo,擁有分支:main (安安), test (你好)
這時候有另一個 pull request 被准許合併至遠端資料夾的 main 分支
遠端資料夾的 main 分支內容由你好→大家好
遠端的資料夾Amigo 目前擁有分支:main (大家好), test (你好)
本地的資料夾Amigo,擁有分支:main (安安), test (你好)
為了先同步遠端 main 分支的最新程式碼,先執行 fetch
遠端的資料夾Amigo 目前擁有分支:main (大家好), test (你好)
↓fetch
本地的資料夾Amigo,擁有分支:main (大家好), test (你好)
再將本地資料夾的 main 分支合併至本地的 test 分支
↓
遠端的資料夾Amigo 目前擁有分支:main (大家好), test (你好)
本地的資料夾Amigo,擁有分支:main (大家好), test (大家好)
# Step by Step
## 把Github上的檔案同步至本地
### Step 1 將**main分支**中的檔案同步到我分支中-->fetch
1. 點擊右上角fetch
- fetch 命令只會下載資料到你的版本庫——它並不會自動合併你的任何工作內容,也不會自動修改你正在修改的東西; 當你準備好合併你的工作內容時,你必須用手動的方式進行合併。
2. 將branches從main改回自己的分支(origin/one-jaiy)
- 注意:點開 Current Branch (第一張照片),先點選到自己的branch,再送出
3. 按確定(choose a branch to merge into one-jaiy)
4. Amigo-TravelerMap
### Step 2 將我分支中的檔案同步到我本地端-->merge
1. 點擊中間按鈕 Current branch,選自己的分支

下圖中的三角形警告是自己分支文件與本地端文件有衝突(conflicted)的意思,依然可以merge下來,再解決衝突點。此狀況發生時,建議先不要merge,先跟Dahis討論過後行動。

## 把本地上的檔案同步上Github
### Step 1 將我本地分支 one-jaiy 中的檔案同步到遠端的相同分支中-->commit+push
1. commit:確認中間有改動的地方無誤後,在左下角寫上本次改動重點,按下commit將資料打包
- 注意:左下角commit前,先確定中間Current Branch 是自己的分支!

1. Push:資料被打包後準備上傳至自己Github的分支中,按下右上角的Push origin將資料上傳,Push後要再按一下Fetch oringin,讓Github獲取資料
- 如果你克隆了一個版本庫, clone 命令會自動增加一個「origin」來代表遠端版本庫; 所以,git fetch origin 會獲取(fetch)在你克隆(或者最後一次獲取)之後任何被推送到伺服器上的新的工作內容。

### Step 2 將本地端分支中的檔案合併遠端**分支**中→提出PR請求
1. 按下 Create Pull Request後,自動打開Chrome版本Github頁面如下圖二


2. 確定頁面中資訊與剛剛commit中寫的一樣,看到最右邊的Reviewers > Suggestions,點開齒輪選Dahis為Code審核者
3. 按下Create Pull Request ,頁面長這樣沒報錯就大功告成

- 備註
1. `git fetch` 的過程中發生了什麼事情?將 origin 有但 local 沒有的版本記錄更新到本機上
2. 什麼時候使用 `git pull`?想要遠端的 branch 和本地端的 branch 同步的時候。`git pull` 其實是 `git fetch` + `git merge` 的組合,簡單來說就是先將遠端的版本記錄複製到本機,再將遠端和本地關係為 upstream 的分支透過 fast-forward 的方式合併。
3. 什麼是 fast-forward ?合併分支時,如果 被合併進去的分支(master) 狀態沒有被更改過,這樣就可以說合併進去的分支(origin/master) 包含所有 master 的歷史記錄,這樣就只要將 master 分支的位置移動到 origin/master 的最新位置上就好,這樣的合併方式被稱為 `fast-forward` 合併。
4. [Github中文說明可參](https://git-scm.com/book/zh-tw/v2/Git-%E5%9F%BA%E7%A4%8E-%E8%88%87%E9%81%A0%E7%AB%AF%E5%8D%94%E5%90%8C%E5%B7%A5%E4%BD%9C)