影片網址:https://youtu.be/g-QIRgkR3Cg
教學文件:https://quip.com/jKX4A8HrkdXb
大部份目前的軟體公司,都是使用 Git Flow 來跑開發流程,這堂課是針對 GitHub Flow 來做 Git Flow 的內容說明。
1-常見合作流程
1-1-Git flow 開發分支的使用差異
在 Git 很早就出現,而當時就有針對團隊開發發展 Git Flow,在 2010 年時就提出了 Git Flow 的開發流程,在裡面有許多的分支。
1-1-1-develop 分支
在 Git Flow 的圖裡,master 分支可能為已佈署在伺服器上的站台,而要開發就由 master 的 Tag 0.1 的點去開分支,開出後由 develop 分支來處理開發的細節。
到了 develop 分支在分別由不同的開發者製作不同的功能,而各自的功能都有自已的 feature branches 的一條線與 commit,在針對功能的開發者製完後在合到 develop 分支上。
1-1-2-relese branches 分支
relese branches 指的是準備要合併要上線的分支,如果進版後就會由 master 合併 relese branches 的內容過去,也就是 master Tag 1.0 的 commit。
1-1-3-hotfixes 分支
如果在 master 分支上的 Tag 0.1 就發現有錯,會在另外開一個分支 hotfixes 來處理 master 上的錯誤修正,在修正完成後在由 master 合併過來,也就是 Tag 0.2 的 commit 記錄。
1-2-GitHub flow
1-2-1-GitHub flow 主要的流程
1. 在 master 建立分支來新增功能
2. 開始開發功能
3. 發 PR (Pull Request) 申請合併
4. 討論與檢視程式碼
5. 部署(Deploy)
6. 合併(Merge)
1-2-2-Git Flow 開發分支與 master 分支說明
在 GitHub 上所使用的 Git flow 方式來開發,主要也是同樣由 master 分支另外開開發與功能分支,像是如果要開發一個 f/view 的功能,就在 master 分支開一個 f/view 分支出來與切換到分支上去獨立開發。
1 2 3 4 5 6 | git barnch f/view git checkout f/view git commit git commit // f/view 分支的獨立功能開發完成,接著要合給 master 分支 git chekout master git merge f/view --no-ff // 讓線圖不快轉,長出小耳朵 |
1-2-3-GitHub Flow 的過程 (PR、Discuss and review、Deploy、merge)
在 GitHub Flow 裡提到,在 master 分支線上開發者,第一件事就是建立新分支 (create a branch),而在 master 線上的 commit 都可可佈署的版本。
當開一個新的分支後,就接著會來增加 commit 記錄,在圖中是增加三個 commit 記錄。
如果開發處理的內容都差不多了,就會發出針對分支合併的請求 (Pull Request 簡稱 PR),希望可以合併到 master 分支上。
在發出 PR 之後是會經過相關的討論,針對提出 PR 的部份來討論與檢視 (Discuss and review your code),確任沒有問題時才會由 master 分支管理者,同意合併到 master 分支上。
在討論完後會進入到部署 (Deploy) 的動作,課程中是為了近於真實,所以會使用 node.js 佈署到 heroku 的主機上,來完成 GitHub Flow 流程。
最後完成的部份就會是 merge 到 master 分支上。
2-協作流程
2-1-情境與執行步驟
1.本地建立 node 、Git 環境,增加 (.gitignore)
2.commit 1:建立環境
3.commit 2:修改 title
4.新增 dev branch
5.新增 GitHub Repo,並 push
6.新增 heroku Repo,並 push
7.Ray 抓 GitHub dev 分支,並開 feature 分支 (中間洧杰做 heroku 部署設定)
8.commit 兩個後,push feature 分支,並開 pr 請求合併 dev
9.管理員合併
10.志誠 抓 GitHub dev 分支,並開 feature 分支
11.commit 兩個後,push feature 分支,並開 pr 請求合併 dev
12.管理員合併,並抓下來看內容都 ok
13.管理員 fetch 下來,用 master 合併 origin/dev 分支,並 push 到 GitHub
2-2-本地端建立 node.js 環境與 GitHub
1 2 3 4 5 | cd desktop // 移動到桌面 mkdir node cd node git init express -e // 建立 Node express 環境 |
目前是要先建立 express (ejs) 的環境,而接立後會在 node 資料夾內有相關的資料。
接著在輸入 npm install 將相關的插件安裝與下載,載完後輸入 npm start 執行環境,在瀏覽器網址列輸入 127.0.0.1:3000 就可以看到 EJS 所建的頁面。
通常會有管理者會將環境建立好,建好後在由其他的工程式做細部的開發,就會有環境與遠端主機設定好,目前主要是協作流程執行步驟的 1-6 的部份。
2-3- .gitignore 不進入版控的設定
在專案資料夾內將 node_modules 資料夾做忽略,在檔案輸入完後存檔,此時 VSCode 的右方資料列表裡的 node-modules 資料夾會呈現灰的狀態,這樣表示沒有進入版控中。
終端機上輸入 git status 查看,可以看到 .gitignore 這支檔案加入,另外在 node_modules 資料夾因為被排除所以不會出現在加入索引的列表中。
接著將設定加入索引入,輸入 git add . 與 git commit -m '新增環境' 新加入一個 commit 記錄。
目前為此是在協作流程的第 2 步驟。
2-4-修改內容後更新,確任新的 commit 記錄
開啟專案資料夾裡的 index.ejs 檔案,在路由的部份加上 - hexschoo 的字串。
使用 git status 確任檔案是否有更動。
1 2 | git add . git commit -m '修改標題' |
接著使用 SourceTree 來看目前的的記錄,目前的話是有二個 commit 記錄。
2-5-新增 dev branch
新增一支分支命名為 dev,主要是不要讓沒確任過的內容直接產生於 master 分支裡,這裡輸入指令 git branch dev。
2-6-新增 GitHub Repo 並 push
在 GitHub 新增一個 Repo 名命為 node-practice,接著將建的 Repo 載到本地端,將 ...or push an existing repository from the command line 裡的二個指令貼到終端機內並執行。
將本地端的專案資料 push 上去 GitHub 完成後,在到頁面更新可以看到所有的檔案都推送到 GitHub。
2-7-新增 heroku Repo 並 push
heroku 是透過 GitHub 的 commit 來更新主機裡的內容,比較像是遠端主機的概念,如果這些觀念都了解只要下指令就可開個伺服器,相當方便。
在分支 origin/master 指的就是 GitHub 裡的 master 分支。
GitHub 為了讓其他參加的開發都,能開到 dev 分支的遠端,所以要在加入 git push origin dev,讓目前自已本地端的 dev 分支推上遠端主機給其他開發者取用,而在 GitHub 裡就會有二個分支出現。
在 GitHub 上的遠端分支處理好後,接著就可以處理 heroku 的遠端主機設定,輸入指令 heroku create。
在完成建立主機時,就會產生一個英數的編號,反選的這就是伺服務的編號。
在使用 heroku create 語法時,也會在 GitHub 數劇庫加一個遠端數劇庫的名稱,在專案資料夾裡的 .git > config 檔中查看,可以看到 GitHub 在第一個 [remote 'origin'] ,而 heroku 是在第三個 [remote 'heroku']。
查看 heroku 主機列表,使用新建所產生的主機編號,查到後點按進入主機的設定頁面。
要將主機內容佈署使用,所以點按右上方的 More 按鈕裡的 View logs 項目,另外可以看到右下方有二個 commit 更新的記錄點。
進入到 View logs 頁面,裡面主要是主機運作的事件記錄,接著要將最新的 commit 記錄更新上主機,就會自動做佈署的動作,輸入 git push heroku master ( heroku 指的是遠端分支的名稱)。
執行指令後會在 log 記錄裡在多出 Build 的事件,
另外到主機狀態的頁面裡,最新使用 commit 的記錄點,也就是最新 Latest activity 的部份,也會有運作的圖示在跑,目前主機的狀態就是在佈置中。
執行到最後完成,在 log 頁面會出現佈置成功 (Build succeeded) 的訊息,另外下方會重新運行 node.js。
回到主機狀態的頁面,就會看到最新的 Latest activity 圖示就沒有在出現有動態的效果。
在終端機裡的訊息就會回應佈置成功 deploy ... done。
在輸入指令 heroku open 可以打開主機的頁面並前往。
目前的遠端數劇庫共有 heroku 與 GitHub 二個,GitHub 有 master 與 dev 二支分支。
2-8-GitHub Flow 配合 heroku 遠端,多人協作與實際佈署
2-8-1-環境建好後對 master (主線)、開發 (dev)、功能 (feature) 分支與協作開發者的使用區別
目前的關係是開發者杰與 GitHub 上同時有二個 comimt 記錄,在建好環境後要交辨給其他工程式接手其他開發的細節。
說明開發時所定的開發規範,不能直接於 master 分支做修改,需要由 o/dev 分支上針的開發,而且也不能直接在 o/dev 分支直接開發,要在由 o/dev 另外開出分支針對功能的 f/router 獨立分支來開發,在功能獨立的分支上開發完成後,透過發 PR 的動作來確任開發的內容合併於 o/dev 分支上,由分支管理者確任沒問題後,才會由 master 分支將 o/dev 分支做合併進來的動作。
過程中在協作開發的工程是是不會接觸到 master 分支,在管理上也會比較單純。
2-8-2-協作開發者針對開發 (dev) 分支,另外開出獨立的功能分支 (feature),在完成處理後推上遠端並提出 PR
協作開發者接收到環境建好的訊息,將接手處理細部的開發,先使用 git clone 將遠端數劇庫載到協作開發者的本地端。
Ray 將遠端分支載下後,就會在 dev 分支另外在新開一個 f/router 分支。
另外開出來後將增加與修改的內容,會於本地端的 f/router 在多加上一個 comimt ,在多加上一個本地端的 commit 與 o/dev 分支上。
接著將修改與新加入的內容,使用指令 git push origin feature/router 推上遠端的主機上。之後會在透過發 PR 請求合併到遠端的,此時遠端上就會在產生一個 r/f/router 的請求合併的 commit ,是由協作開發者 Ray 本地端的 f/router 所送出 PR 到遠端所產生。
送出 PR 後可以到 GitHub 看到 Pull requests 多一則訊息。
2-8-3-GitHub PR 的討論與分支管理者合併
進入到 PR 的訊息列表頁面中,點入對應的 PR 標題 (修正 Rotuer 標題) 頁面。
進入 PR 頁面後,點按 Commits 頁籤查看修改過的內容。
進入 commit 後到修改的字串,將 title 的字串改成 六角 Git 特訓班,可以看到所改的檔案是 routes/index.js 這支檔案。
切回討論頁面,在 commit 的部份進行訊息留言來做相關的討論。
協作開發者 Ray 就回應在論討串中做回應。
在進入到修改 commit 裡所修改過程式碼部份,移到修改的上方會出現一個 + 的按鈕,在點按後會出現訊息框針對程式碼與區塊做討論與留言。
程式碼裡直接留言有二種狀態,一個是單行的回饋,另外一種是 code review ,直接針對程式碼區塊來做討論,這裡是直接使用單行回饋
送出後切換到 PR 的訊息列表頁 (Pull requsests > commit 標題 > 進入到標題頁面中 ),此時單行回饋留言的部份,就會帶到 PR 標題頁面中顯示,另外也可以看到協作開發者針對單行程式碼所進行的回應留言。
2-8-4-點按 PR commit 標題討論程式碼,在瀏覽器上產生該行程式碼的位置編號
點按程式碼行數,會在網址列產生對應的位置行數參數,可以將網址完整的拷貝起來,進去到留言列表區內在進行該行程式碼的討論。
在 PR 裡會經過相關的討論與 code reviwe,又或是主管在查驗程式碼功能,所以在 GitHub 上是很注重討論與協作上的 code reviwe 的部份。
2-8-5-分支管理者確任 PR 沒問題後,o/master 進行分支合併
在經過相關的討論與確任沒問題後,接著就是將分支做合併上 master 的動作,有時在合併 PR 時會發生衝突,不過目前是沒有發生。
可自訂合併 PR 的 commit 訊息,而如果按下 confirm merge 按鈕時,點按下去後就會回應合併成功 (),而後方就會出現刪除合併分支的按鈕,合併 PR 分支就管理者要不要刪除,有時是個重要的合併還會在改與變動,因為協作的開發者本機上也還有原本 PR 的分支所以刪除也行,不過目前是將分支先保留不刪除。
就會在 o/master 上在產生出一個新的 commit 記錄點,而 o/dev 分支就會移到最前面。
使用 SourceTree 查看,先點按 Fetch 將遠端分支下戴進本機,可以看到 o/dev 與 o/f/router 分支同上方的線圖一樣,在 PR 合併後會產生一個 commit 出來,最後成為一個小耳朵。
2-8-6-第二個協作開發者 (王志誠) 接續開發其他功能 (f/view)
假如前面在合併 PR 的部份,如果有將分支刪除的話,在後面 clone 遠端分支的開發者,是看不到之前的 PR 合併分支,在每個開發者線圖的狀態都可能會不太一樣,以第一個開發者 (Ray) 的本機端,是還會有 f/router 分支存在。
在第二位開發者將 GitHub clone 進本機端時,其實只會有單純的 o/master 與 o/dev 分支在線圖上,在 GitHub 如果 PR 所刪除分支之下,在第一位開發者 (Ray) 那也還是會有保留。
接著第二位開發者會在本端端建 dev 與在建 f/view 的分支,
2-8-7-Heroku 自動將 GitHub master 新增的 commit 做自動化佈署
GitHub 可以設定 Heroku 在 master 線多加上 commit 後,自動觸發 Heroku 的自動佈署,在設定介面中裡的 Deploy > GitHub 設定,用來整合指定的 Repos ,指定好後做連接。
在 Heroku 裡的 GitHub 項目中有 Automatic deploys 項目中,可以指定自動化佈署的指定分支設定,另外下方的 Manual deploy 的是手動佈署,這裡使用自動化佈署,當 GitHub 的指定分支上有新的 commit 點時,也就是 o/master commit 有新的,就會自動化處理。
點按下自動化佈署後,就會出現 Automatic deploys from master ... 的訊息,另外頁面上方也會顯示自動化佈署所指定的 GitHub 數劇庫與分支名稱。
2-8-8-第二個協作開發者使用的 GitHub Flow 指令,發送 PR
1 2 3 4 5 6 7 | git clone git checkout dev git branch feature/view // or feature/add_view or feature/fix_view or feature/mod_view git checkout feature/view git add . git commit -m '' git push origin feature/view // 此時提出 PR 的合併請求 |
目前第二個協作開發者將新增的 f/veiw 分支發出 PR,而線圖目前還沒有由分支管理者確任通過再進行合併。
切換到 PR 的頁籤上查看,在 PR 的列表上看到 commit 標題內容,點按下之後進入 PR 內容頁面。
這裡可以看到 feature/view 的分支,透過 PR 要合併於 dev 分支裡,另外在確任 PR 進行合併前的相關討論。
有時開發者會移動錯分支,這裡確任是由 feature/view 分支透過 PR 要合到 dev 分支上。
在討論的過程中,如果發現程式碼有點問題,在 PR 合併的部份就先不要處理合併,先刪遠端分支在重新處理,但如果按下 Merge Pull request 按鈕後,就等於 PR 透過合併分後,將資料合併進行同時也加上一個新的 commit,而 o/dev 分支的標籤就會移到前面。
實際在開發上, dev 是不會自已產生出新的 commit 記錄點出來,是透過 PR 所合併出來的結果。
按下 Merge Pull request 按鈕進行 PR 的合併,而合併成功後的刪除分支,一樣就先不刪留著。
切到 SourceTree 上查看,點按 Fetch 將遠端的內容載到本機端
GitHub 的 Fetch 完成後,就可以看到 o/dev 分支透過 o/f/view 分支 PR 所合併後,所新增一個小耳朵的 commit 記錄。
目前的話進行到情境與執行步驟的第十一個步驟 – commit 兩個後,push feature 分支,並開 pr 請求合併 dev
2-8-9-管理者針對 PR 過的 dev 分支,先在本地端的 master 分支合併遠端 dev 分支後,在推向遠端的 master 分支
管理者確任過 o/dev 分支裡的內容是完全運作上沒有問題,接著就需要將 o/master 合併取得 o/dev 分支裡的內容,將 commit 往前移達到內容同步。
可以在 GitHub 上直接處理 PR 合併,這樣的方式是管理者自已對自已發出 PR 來合併,但要在進一步確定新加入功能後的 o/dev 分支,在內容上是沒有問題所以可以將遠端分支上的所有分支都載到本地端,在本地端確任新增與修改的部份都完全沒有問題後,在由本地端推到遠端分支上把 o/master 推向 o/dev 同步同一個 commit。
目前透過 Fetch 將遠端分支的 o/dev 都載到本地資料夾中,使用 Fetch 將遠端資料抓下來後,相關的檔案也都會存於 .git 裡面,也因為取得遠端分支的 o/dev 裡的相關內容與檔案,所以就可以透過本地端的 master 分支向 o/dev 合併,合併的動作都是由本地端完成。
確任好取得 o/dev 裡的內容沒有問題後,就可以由 master 的本地分支,使用指令 git merge origin/dev,輸入完指令後就會將本地端的 master commit 快轉到同樣的 o/dev 分支上同一個 commit 上,而指令輸入也會同步施行快轉 (Fast forward)。
目前本地端的 master 分支,也與 o/dev 同步同於一個 commit 記錄上,在目前的 master 上的 HEAD 前面寫著 4 ,就是指將二個透過二次新加功能的 o/dev 分支,所取進的 commit 記錄產生了四個。
接著就要將合併好的本地分支 master 推向遠端,使用指令 git push origin master,此時的 o/master 也會移向 o/dev 同一個 commit 記錄點上,終端機上也回應更新成功的訊息。
切換到 heroku 的主機後台,確任 GitHub 分支更新後,也確實自動化將 master 的最新的 commit 記錄做自動化的處理。
heroku 主機自動更新最新的 master 記錄。
Latest activity 列表中最上面就是最新的 commit 記錄,目前是在上傳處理,要看主機正式的頁面點按下右上方的 Open app 按鈕,就會自動開啟發佈佈署的頁面。
最後 SourceTree 的線圖 o/master 與 o/dev 與本地端的 master 都在同一個 commit 上面。
3-slido 發問
3-1-Q-遠端上的線圖合併時不會快轉 ?
A: 發 PR 時一定會產生一個新的 commit 記錄,在這樣的情形下一定會產生小耳朵的情形,不會有快轉產生。
3-2-Q-pull = fetch = merge ?
A: 對,fetch 就是先將遠端的檔案抓下來,但是還沒有 merge,在開發時比較好的習慣是先將遠端 fetch 下來看過資料,確任後在決定要不要 merge。
3-3-Q-私人公司 REPO 協作,需要主要帳號授權或是 SSH + 金鑰的方式嗎 ?
A: 需要,這樣才可以取得授權。
會不會有人把 master 分支刪除,如果刪除的話就 GG 了。
進入 GitHub 裡的 Settings,裡面有個 Branches 項目,在進面有 Branch protection rules (保護規則) 的設定,要加入設定點按右方的 Add rule 按鈕。
進入規則的設定頁面,可以指定 master 分支,Rule settings 設定指分支名後,就會預設不能刪除 ( Desabiles force-pushes to all matching branches and prevents them from being deleted. ),另外也可以設定透過 PR 方式合併項目 (Require pull request reviews before merming),一定要透過 PR 才能合併。
在 Branch protectionrules 的部份,列出附合的分支名 masetr ,有一個分支附合規則 (Currently applies to 1 branch),此時就不會很容易的被刪除。
3-4-Q-第五步驟,push master and then tush dev 在本地需要切換分支嗎 ?
A: 要,要切換到 git checkout dev 後,才可以將本地的 dev 分支推向遠端
3-5-Q-如果 PR 時的討論發現有錯誤,不在線上條改的話,要重新 commit 再重發 PR ?
A: 如果 PR 失敗,討論後確任不行就可以刪除遠端分支,而本地端的部份在做新的分支與製作新的 commit,例如使用 git reset 還原後,在接著新製作新的分支或是版本,完成後在重請 PR。
3-6-Q-Git Flow 好難
A: Git Flow 是 2010 年出來,而 GitHub Flow 也是近期較新的開發流程,比較嚴僅主要是討論後透過 PR 處理後才 merge 成功。
有時後還要等 PR 的流程處理,如果二三位是差不多能力的開發者沒有上下關係,想自已合併 PR 或是合併 commit,團隊自已討論好後不用一定合於 PR 的規則,也可以高速的開發,而 PR 也不一定是在開發過程中一定需要的,如果公司是有制度的話,一定希望協作的人員,不希望較初階的工程師去壞了線圖,透過 PR 的機制來保護主要的分支,而協作的人可以給予拉下 o/dev 的權限來處理新開發或是修改的內容。
3-7-Q-請問自動部署是因為 heroku 自動設定的關係嗎 ?
A: 沒有錯,在 heroku 的 deploy 項目裡會有個 Deployment method (部署的方式) 用那一種,這裡是選用 GitHub,在 Conenct to GitHub 裡指定要同步的 REPO,設定好後就會針對 master 自動部署,如果有新的 commit 記錄就會自動處理,將 GitHub master 分支與傳一份到 heroku 的主機分支上。
為何要選好 Git ,主要是因為主機自動佈署時是透過 Git 的 commit 達到自動化處理,但有的軟體公司會怕自動化的過程有問題,例如有驗証、測試,所以在 Heroku 自動化設定中還有個項目等 CI 執行完成 (Wait for CI to pass before deploy),讓測試流程都過了之後才做佈署到主機的動作。
另外,也有怕有其他問題,所以也會以手動佈署為主。
3-8-Q-自動部署會直接覆蓋 master 嗎 ?
A: 覆蓋的意思不對,因是使用合併,是由 GitHub 的合併合併到 Heroku 分支,而這是 Heroku 主機的功能,使用 node.js 寫才可實現。
3-9-Q- .gitignore 可以針對不同分支獨立設定嗎,約是如何使用的情境才用的到 ?
A: 大部份都是全域共用,在 git 開發一定會有忽略清單的設定。
每個分支的 .gitignore 內容設定可不同,很少會設定到不同的清單內容。
3-10-Q-為何 dev 是指向 o/dev ? 而不是二個都指向該 commit 節點 ?
A: 使用 git fetch 將遠端的 o/dev 分支抓下來,在本地端的專案資料夾裡的 .git 資料夾,裡面其實也就會有 o/dev 的檔案資料,所以就直接使用本地端的 masetr 分支,直接 git merge 下戴下來的 o/dev 分支,讓 commit 同步後在 push 遠端 GitHub 上。
而二個節點不是一開始就移動本地端的 dev 分支,當然也可以會切到本地端的 dev 分支,在合併 o/dev 的分支,這樣也是可以。
但開發時是希望可以直接或一直抓下遠端最新的資料,所以就先抓 o/dev 分支,使用 git fetch 遠端分支,下載完後在針對新的功能做開發,而本地端的 dev 就不用接觸到,因為可能同時會有多位的開發者,會可能更新資料上來,只要針對 o/dev 有沒有新的東西,只要 git fetch 下來後只要針對新的東西,在將自已的 master 再與新的 o/dev 做合併,