在上「進階Git」時,ihower介紹了「Git flow v.s. GitHub flow」兩者最大的差異在核心精神。
Git flow
- git flow相對嚴謹,Git的架構中,分成五類的branch,「feature branch」「develop」「release branch」「hotfixes」「master」。feature branch從develop分支出來,所有要開發新的功能都會開一個新分支;release branch是準備要release的分支,會在修完所有bug後merge進master與develop。master與develop靠著release來做整合。
- 當產品是安裝在客戶端的application時,會偏好使用Git flow。
- GitHub flow相對較彈性,也會是我們這組在Alpha camp專案使用到的流程。架構中,主要分成兩類,master與feature branch。當要開發一個新的功能時,就開一個新的分支,完成後merge進master。
- 適合如網站開發,deploy的次數相對多次且具彈性的專案。因為一旦發現錯誤,只要修正後,使用者再訪便能使用到最新的版本,嚴謹度相對gitl flow的(性質不同、需求不同)但比起Git flow,較輕量化。
- 以精神來說,master的任何一個commit都要deploy上去(無論是production還是staging),新的功能就是一個新的分支,完成的時候發pull request,在大家review後,才merge進master
專案Git流程
1. 當要做新功能時,我們需要一個新的branch來代表這個功能,所以從master開一個新的 branch
git checkout -b new_feature
2. 新的branch需要push到遠端,讓隊友們知道我現在的進度
git push origin new_feature
3. 在功能完成後,我們預計要將新功能merge進去,我們需要最新的master
git checkout master
git pull
4. 有了最新的master,要將已經完成的branch rebase在新的mater上面
git checkout new_feature
git rebase master在處理rebase的過程中,建議開著GUI,明確看到衝突點是什麼、預計改成什麼樣子,每一次處理完conflict後git add . 將修改過的衝突點加到staged area
git rebase --continue處理完所有的衝突後,分支就會建立在最新的master上啦!
5. 處理完 conflict 完後,為了讓隊友們可以review我rebase完的code,我需要將code上傳到github上
git push -f origin new_feature (我個人不會使用這做法,會保留就有的branch)
我的習慣會希望留著舊有的new_feature在原地(rebase前),我會在master開一個branch,來將rebase過的new_feature推到遠端
git checkout master
git checkout -b new_feature_v2將new_feature的每個commit cherry-pick進到 new_feature_v2git push origin new_feature_v2
6. 發pull request,大家review過後,再merge進maste
7. 當大家都review完後,就可以merge了!
git merge new_feature --no-ff
8. 當新功能完成且已經在本地與遠端merge進master後
git branch -d new_feature
git push origin :new_feature
其他常用Git指令
git rm --cached file_name 已經commit過但想要解除追蹤git branch new_feature 開一個新的分支
git checkout -b new_feature 開一個新的分支並盡到該分支
git branch branch名稱 起始點 起始點可以是一個 tag,branch 或是 commitgit branch -d <branch> 當完成新功能後,將branch刪除
git push origin :<branch> 當完成新功能後,將遠端branch刪除git checkout other_branch 進到other_branch這個分支
git checkout -b "branch名稱"git rebase 將「原來的branch」的最新狀態當作此branch起始點,將「原本的branch」merge進停留的branchgit reset HEAD^ 取消上次的commit,但檔案還在,但staging是空的
git reset HEAD^ --soft 取消上次commit,但檔案還在,且staging還在
git reset 將staged的檔案,拉回unstaged
git reset --hard 將staged的修改全部刪除(untracked的不會刪,staged、unstaged的會刪除)
(^ 是「前一個版本」的意思)git branch -m old_name new_name 修改branch的名稱
參考網站
ihower https://ihower.tw/git/
http://blog.gogojimmy.net/2012/01/17/how-to-use-git-1-git-basic/
http://blog.krdai.info/post/17485259496/github-flow
http://fireqqtw.logdown.com/posts/196392-git-casually-notes#reset