如何與 Git 優雅地在樹上唱歌
Kewang
Who I am
● 王慕羣 Kewang
● Java / Node.js / AngularJS
● HBase / SQL-like
● Git / DevOps
●
熱愛開源
GitHubGitHub kewangkewang
LinkedinLinkedin kewangtwkewangtw
SlideShareSlideShare kewangkewang
GmailGmail cpckewangcpckewang
FacebookFacebook Kewang 的資訊進化論Kewang 的資訊進化論
HadoopConHadoopCon '14 '15'14 '15
MOPCONMOPCON '14'14
JCConfJCConf '16'16
What Mitake is
三竹資訊
● Qmi:企業內部即時通訊軟體
●
全國最大的企業簡訊平台
● 市佔近 100% 的行動下單
● 市佔近 70% 的行動銀行
●
企業內部應用、產壽險、金融相關政府機關
● MicroCoin 、兌彩券、台灣匯率、三竹小股王、行動股市
GitHubGitHub mitaketwmitaketw
4
mind map
5
6
存取模型
7
分散式貢獻者模型
dispersed contributor repositories
8
9
10
11
12
共處一地貢獻者模型
collocated contributor repositories
13
14
15
16
17
共享維護模型
shared maintenance repository
18
19
20
21
22
套用單一 <commit>
git tips
23
git cherry-pick
git tips
24
git cherry-pick
●
git cherry-pick <commit>
– 通常是在 production 修正 bug 後,把同一個 bug 也在 dev
修復
● git cherry-pick -e <commit>
– 在 cherry-pick 前先編輯 commit message
– 可以搭配 mention 功能,將某個 issue 關閉
●
git cherry-pick -n <commit>
– cherry-pick 時先不 commit ,而是放到 index 裡面一次
commit
– 通常用在大範圍的 <commit> 上面,類似 squash
git tips
25
分支策略
26
主線開發
27
28
29
主線搭配分支開發
30
31
32
33
34
用 git 找 bug
git tips
35
git bisect
git tips
36
git bisect
● 當某個 bug 出現,但卻無法得知是哪個
<commit> 造成時的好用工具
● 利用二元搜尋標示可能出錯的 <commit>
●
必須有良好的開發習慣,每完成一個小段落並且
可以編譯成功就馬上 commit ,而不是一次完成
很大的功能才 commit
git tips
37
一功能一分支
Dymitruk Model
38
39
40
41
42
GitHub Flow
43
44
45
用 git 找戰犯
git tips
46
git tips
47
git blame
git tips
48
git blame
● 每一行的 <commit> 分別是哪些人修改
git tips
49
git blame
● 每一行的 <commit> 分別是哪些人修改
● 方便開發者溝通 (!?)
git tips
50
GitLab Flow
51
52
53
gitworkflows
54
55
56
GitLab Flow & gitworkflows
57
GitLab Flow & gitworkflows
58
GitLab Flow & gitworkflows
●
優點
– 分支名稱符合情境
– 合併進度時更易使用正確的分支
59
GitLab Flow & gitworkflows
●
優點
– 分支名稱符合情境
– 合併進度時更易使用正確的分支
●
缺點
– 必須要有指南才能知道從何開始
– 分支名稱與情境有高相關性,很難在不同專案建立一
樣的結構
60
找到遺失的 <commit>
git tips
61
git tips
62
git reflog
git tips
63
git reflog
● 有幾乎全部的 <HEAD> 記錄
● 常用來找某個 merge 或 reset 的 <commit>
git tips
64
git reflog
● 有幾乎全部的 <HEAD> 記錄
● 常用來找某個 merge 或 reset 的 <commit>
● 可能會被 gc 導致 log 不見
git tips
65
GitFlow
66
67
68
69
70
Qmi flow
還沒想名稱,姑且先用這個代替吧
71
72
73
74
75
部署謊言
deployment lies
76
部署謊言
77
部署謊言
●
程式碼不會真的從本機伺服器走到正式機伺服器
78
部署謊言
●
程式碼不會真的從本機伺服器走到正式機伺服器
● 開發完時將編譯後的執行檔上傳至 artifact
server ,部署時應從 artifact server 下載,並使用
md5sum 確認
79
部署謊言
●
程式碼不會真的從本機伺服器走到正式機伺服器
● 開發完時將編譯後的執行檔上傳至 artifact
server ,部署時應從 artifact server 下載,並使用
md5sum 確認
●
避免程式碼變更,造成測試機及正式機上的執行
檔不同版本
80
部署謊言
●
程式碼不會真的從本機伺服器走到正式機伺服器
● 開發完時將編譯後的執行檔上傳至 artifact
server ,部署時應從 artifact server 下載,並使用
md5sum 確認
●
避免程式碼變更,造成測試機及正式機上的執行
檔不同版本
● 若使用有部署的 flow 時,部署完後記得將程式碼
合併至下一流程所用到的分支
81
GitLab 使用經驗
82
專案可視度
Visibility Level
83
專案可視度
84
專案可視度
● Private :必須明確指定使用者權限
● Internal :能登入 GitLab 就能 clone 專案
● Public :不需要認證就能 clone 專案
85
我的建議
86
我的建議
● Private :適合需要權限控制嚴謹的專案
87
我的建議
● Private :適合需要權限控制嚴謹的專案
– 如:封閉專案、剛從 SVN 轉換過來的專案
88
我的建議
● Private :適合需要權限控制嚴謹的專案
– 如:封閉專案、剛從 SVN 轉換過來的專案
● Internal :使用 fork 及 MR 讓可受限制的開發者
協同開發
89
我的建議
● Private :適合需要權限控制嚴謹的專案
– 如:封閉專案、剛從 SVN 轉換過來的專案
● Internal :使用 fork 及 MR 讓可受限制的開發者
協同開發
– 如:同專案不同系統、同部門不同專案、同公司不同
部門
90
我的建議
● Private :適合需要權限控制嚴謹的專案
– 如:封閉專案、剛從 SVN 轉換過來的專案
● Internal :使用 fork 及 MR 讓可受限制的開發者
協同開發
– 如:同專案不同系統、同部門不同專案、同公司不同
部門
● Public :使用 fork 及 MR 讓外部開發者協同開發
91
我的建議
● Private :適合需要權限控制嚴謹的專案
– 如:封閉專案、剛從 SVN 轉換過來的專案
● Internal :使用 fork 及 MR 讓可受限制的開發者
協同開發
– 如:同專案不同系統、同部門不同專案、同公司不同
部門
● Public :使用 fork 及 MR 讓外部開發者協同開發
– 如:開源專案
92
權限等級
Access Level
93
權限等級
94
權限等級
● Owner :專案建立者,如部門經理,變更專案能
見度、移除專案
● Master :專案執行者最高等級,如小組長,建立
專案、建立里程碑、操作受保護的分支、建立環
境變數、建立 trigger
● Developer :一般開發者,建立 MR 、建立分
支、操作不受保護的分支、新增 tag 、建立 wiki
● Reporter :回報者,取得所有程式碼
● Guest :訪客,建立 issue 、留言、觀看 build
log 、下載 build 完的產生物
95
Git for Teams 的建議
96
Git for Teams 的建議
● Owner :不屬於團隊的管理人員
97
Git for Teams 的建議
● Owner :不屬於團隊的管理人員
● Master :專案領導者及聰明的專案管理人員,可
能會需要隨時間調整團隊組成及權限
98
Git for Teams 的建議
● Owner :不屬於團隊的管理人員
● Master :專案領導者及聰明的專案管理人員,可
能會需要隨時間調整團隊組成及權限
● Developer :團隊中的大多數成員,可以限制個
別成員對特定分支的存取
99
Git for Teams 的建議
● Owner :不屬於團隊的管理人員
● Master :專案領導者及聰明的專案管理人員,可
能會需要隨時間調整團隊組成及權限
● Developer :團隊中的大多數成員,可以限制個
別成員對特定分支的存取
● Reporter : CTO ,因為不太會直接寫程式碼
100
Git for Teams 的建議
● Owner :不屬於團隊的管理人員
● Master :專案領導者及聰明的專案管理人員,可
能會需要隨時間調整團隊組成及權限
● Developer :團隊中的大多數成員,可以限制個
別成員對特定分支的存取
● Reporter : CTO ,因為不太會直接寫程式碼
● Guest :利害關係人 (stakeholder) ,不需存取程
式碼,但應該參與專案開發
101
受保護的分支
Protected Branches
102
受保護的分支
103
受保護的分支
● 只有 Master 等級才可以
– 建立分支
– 推送分支
104
受保護的分支
● 只有 Master 等級才可以
– 建立分支
– 推送分支
● 任何人 ( 包括 Master) 都不可以
– 強制推送分支
– 刪除分支
105
常用在
106
常用在
●
非功能分支僅給特定開發者推送
107
常用在
●
非功能分支僅給特定開發者推送
● 整合分支僅給 Master 推送
108
常用在
●
非功能分支僅給特定開發者推送
● 整合分支僅給 Master 推送
●
禁止小屁孩亂推送或刪除分支
109
把某個版本包成壓縮檔
git tips
110
git archive
git tips
111
git archive
● 壓縮後寄給沒使用 git 的開發者 (?)
git tips
112
git archive
● 壓縮後寄給沒使用 git 的開發者 (?)
● 壓縮後寄給沒使用 git 的弱點掃描系統 (?)
git tips
113
114
SemVer
Semantic Versioning
115
主版號 . 次版號 . 修訂版號
116
主版號 . 次版號 . 修訂版號
● 主版號:不相容的 API 修改
●
次版號:向下相容的功能性新增
●
修訂版號:向下相容的問題修正
● 先行版號及版本編譯資訊可以加到「主版號 . 次
版號 . 修訂版號」後面作為延伸
117
主版號 . 次版號 . 修訂版號
● 主版號:不相容的 API 修改
●
次版號:向下相容的功能性新增
●
修訂版號:向下相容的問題修正
● 先行版號及版本編譯資訊可以加到「主版號 . 次
版號 . 修訂版號」後面作為延伸
● 以 0.1.0 作為初始化版本,並在每次發行時遞增
次版號
118
主版號 . 次版號 . 修訂版號
● 主版號:不相容的 API 修改
●
次版號:向下相容的功能性新增
●
修訂版號:向下相容的問題修正
● 先行版號及版本編譯資訊可以加到「主版號 . 次
版號 . 修訂版號」後面作為延伸
● 以 0.1.0 作為初始化版本,並在每次發行時遞增
次版號
● 1.0.0 版的定義:用於正式環境、穩定的 API 被使
用者依賴、擔心向下相容
119
SemVer + Git
120
SemVer + library
121
SemVer + library
●
不會自動更新
122
SemVer + library
●
不會自動更新
●
除非重大變更,否則每個次版號都必須新開分支
123
SemVer + library
●
不會自動更新
●
除非重大變更,否則每個次版號都必須新開分支
●
重大變更時需增加主版號,並確認是否可相容舊
主版號
124
SemVer + SaaS
125
SemVer + SaaS
●
會自動更新
126
SemVer + SaaS
●
會自動更新
● 無論使用哪種 flow ,最後應該都只有一個正式區
的分支
127
重新整理 <commit>
git tips
128
git tips
129
git rebase -i
git tips
130
git rebase -i
● 使用 <commit>
– pick :不變更 commit message
– reword :變更 commit message
– edit :使用 --amend 變更 commit message
git tips
131
git rebase -i
● 使用 <commit>
– pick :不變更 commit message
– reword :變更 commit message
– edit :使用 --amend 變更 commit message
● 合併 <commit>
– squash :保留 commit message
– fixup :不保留 commit message
git tips
132
git rebase -i
● 使用 <commit>
– pick :不變更 commit message
– reword :變更 commit message
– edit :使用 --amend 變更 commit message
● 合併 <commit>
– squash :保留 commit message
– fixup :不保留 commit message
● 執行指令: exec
git tips
133
git rebase -i
● 使用 <commit>
– pick :不變更 commit message
– reword :變更 commit message
– edit :使用 --amend 變更 commit message
● 合併 <commit>
– squash :保留 commit message
– fixup :不保留 commit message
● 執行指令: exec
● 移除 <commit> : drop
git tips
134
git rebase -i
● 使用 <commit>
– pick :不變更 commit message
– reword :變更 commit message
– edit :使用 --amend 變更 commit message
● 合併 <commit>
– squash :保留 commit message
– fixup :不保留 commit message
● 執行指令: exec
● 移除 <commit> : drop
● 可以隨意變更 <commit> 順序
git tips
135
Redmine 使用經驗
136
使用方式
137
使用方式
● 每個工作都詳實紀錄在 Redmine 上面
138
使用方式
● 每個工作都詳實紀錄在 Redmine 上面
● 開分支時依照 issue number 建立,如 feature/145-
add-oauth 、 bug/286-login-fail
139
使用方式
● 每個工作都詳實紀錄在 Redmine 上面
● 開分支時依照 issue number 建立,如 feature/145-
add-oauth 、 bug/286-login-fail
● issue 處理完畢後,合併到其他分支建議使用
true merge 方式處理,在線圖上會清楚表現出來
140
使用方式
● 每個工作都詳實紀錄在 Redmine 上面
● 開分支時依照 issue number 建立,如 feature/145-
add-oauth 、 bug/286-login-fail
● issue 處理完畢後,合併到其他分支建議使用
true merge 方式處理,在線圖上會清楚表現出來
● issue 處理完畢時,可以加上 mention 的方式直接
關閉 issue
141
使用方式
● 每個工作都詳實紀錄在 Redmine 上面
● 開分支時依照 issue number 建立,如 feature/145-
add-oauth 、 bug/286-login-fail
● issue 處理完畢後,合併到其他分支建議使用 true
merge 方式處理,在線圖上會清楚表現出來
● issue 處理完畢時,可以加上 mention 的方式直接
關閉 issue
● 使用 tj/git-extras
142
遇到的問題
143
遇到的問題
● 沒有每個工作都記錄在 Redmine 上
144
遇到的問題
● 沒有每個工作都記錄在 Redmine 上
● 不知道開 sub-issue 的時機
145
遇到的問題
● 沒有每個工作都記錄在 Redmine 上
● 不知道開 sub-issue 的時機
● 沒有按照 name convention 開分支
146
遇到的問題
● 沒有每個工作都記錄在 Redmine 上
● 不知道開 sub-issue 的時機
● 沒有按照 name convention 開分支
● 不知道要使用 merge 還是 rebase
147
Git for Teams
148
149
References
● Git for Teams
● A successful Git branching model
● The Dymitruk Model
● GitLab Flow
● GitHub Flow
150
References
●
工程團隊如何做專案與程式碼管理 (一)
●
工程團隊如何做專案與程式碼管理 (二)
●
工程團隊如何做專案與程式碼管理 (三)
151
Git 相關社群或開發者
FacebookFacebook Git.twGit.tw
MeetupMeetup GHTUGGHTUG
blogblog AppleBOYAppleBOY
blogblog ihowerihower
blogblog 保哥保哥
blogblog 高見龍高見龍
152

如何與 Git 優雅地在樹上唱歌