iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0
Software Development

Kotlin on the way系列 第 10

Day 10 想回到那天和那場電影 (feat. Git) Wish to back to the night with movie (feat. Git)

  • 分享至 

  • xImage
  •  

Si vous deviez revivre une époque, vous choisiriez laquelle ? 如果時光倒流,你想回到何時
La Belle Epoque 美好拾光公司 7th, 5
Yes

時間總是不斷向前走,每人每刻,都面對著不同的路口,儘管我們都有各自的課題,但相同的是人總在某個深夜,會希望能穿越時間,在某個交錯的緣分中做不同的選擇
.
.
.
你也有想回去的路口嗎?

可惜的是人生沒有重來,那努力讓未來不要留下遺憾吧


但是呢!!! Git 可以喔!!!今天來開始使用 Git 吧,至於為什麼這階段聊 Git,原因很簡單 我想寫小散文 之後的 OOP 概念會比之前的複雜,把 Git 學好,有版控才能寫出更好的 Kotlin 專案(每個語言都是拉XD)


本文結構

  • basic
    • add git into your project
    • git ignore
    • branch
    • commit
    • git rebase and git merge
  • jetbrain ide tool
  • time travel
    • love story in parallel spacetimes
  • git flow
  • summary
  • Reference

basic

use git for version control

創建一個專案,並在 terminal 切換到專案的根目錄,下
git init
已設置 git 追蹤此資料夾包含的內容,這時如果下 ls -a 會發現增加了 .git 的檔案

如果想要移除 git 的檔案管理,git 並沒有指令可以 undo git init ,需要手動輸入 rm -rf .git,個人不喜歡下 rm -rf 但當初的確找了很久,git 是真沒指令處理

git ignore

初始化後,裡面也會增加一個檔案叫 .gitignore
intellij

sample kotlin project

sample web project
他做的是很簡單,就是聲明專案裡哪些檔案或資料夾不要被 git 追蹤,我們可以用 glob 來寫規則

/setting/*.json         # 忽略所有 setting 目錄下附檔名是 .json 的檔案
*.txt                # 忽略所有附檔名是 .txt 的檔案

而這些設置需要 .gitignore 先被追蹤後才會生效,可以先

git add .gitignore
git commit -m "Add git ignore"

完成之後,就可以看到 ide 裡面,會將沒被追蹤的檔案以不同顏色區分,通常我們會將依賴的套件資源以及需要隱藏的變數(Api key)也加入 .gitignore 裡面

當然你也可以使用 git-crypt 來加密

branch

  • 分支的重要性?
    讓開發者在不同分支間互不影響,不僅如此,分支也能用於區隔不同功能,更是 git flow 的基礎
  • 如何開一個分支?
git branch dev //新增 dev 分支
//or 
git checkout -b feat// 新增 feat 分支並切換過去
  • 合併後的分支該如何處理?
    合併過的分支是能留著,但隨著專案變大,通常還是會刪掉
git branch -d feat //可刪除以合併過的 feat 分支
git branch -D test //可刪除未合併過的 test 分支

commit

git commit 是要讓其他開發者,可以透過訊息了解這個節點更動了什麼,如果團隊有固定格式的話請照固定格式,這邊分享一下我現在使用的格式

Type:

  • feat 新增修改功能
  • fix 修正bug
  • style 程式碼格式,不影響程式運行的更動
  • refactor 重構
  • tests 增加測試
  • doc 文件
  • chore 建構程序或輔助工具的變動
  • BREAKING CHANGE 重大變更
[type] subject

body

fotter

而實際打出來可能會長這樣

[feat] : 用戶登入功能

需求:
 email 用原生格式驗證
 密碼以正規表達式驗證

調整項目:
1. EmailValidator.kt,使用 Patterns.EMAIL_ADDRESS 驗證。
2. PasswordValidator.kt,使用後端提供格式驗證。

Reviewed-by: @Team member
Refs #6

請一定描述原始問題,不要假設閱讀者能知道,連你在一個月後都不一定能想起來了

git rebase and git merge

兩者的差異在接合兩個分支時最明顯,假設 dev 上面開了兩個分支,user, payment

user1 -> user2  
001100 -> 110011 

payment 
090909

用 merge 接合的話, git 會取個分支最後的結果,檢查是否有衝突,並新增一個 commit 節點

//user branch 
git merge payment

user1 -> user2 -> payment -> merge paymeny into user
001100 -> 110011 -> 090909 -> 686888

用 rebase 接合的話,git 會接

//user branch
git rebase payment
payment -> user1 -> user2
090909 -> 776678 -> 899362

值得注意的是,rebase 會該改 commit 節點紀錄,如果你的節點已經推出去給別人用了,就不建議用 rebase 操作
rebase 本質上是把 user branch 的每個 commit 拿一份去 payment 後面,並重新計算 sha 值,最後再把 user branch 指向 889362 , Head 指向 user branch

jetbrain ide tool

jetbrain 的 ide 裡面有內建一些工具,筆者認為最有用的就是 Reformat, Rearrange, Optimize 了,如果透過 ide 下 git commit 也不用特定開 vim 寫訊息,還能自動幫你整理一些 code ,儘管關閉檔案前用快捷鍵整理是禮貌,但筆者這種金魚腦還是靠工具實在

time travel

已經 push 出去的 commit 只用 revert 更改,reset, rebase 都會造成平行時空

reset

真正意義上的回去,如果已經 push 出去,而在本地新增其他節點,就會有平行時空出現

001100 -> 110011 -> 066660
$ git reset HEAD^ --hard
001100 -> 110011

revert

revert 是新增一個 內容和 110011 一樣的節點,來取消 066660 所新增的更動

001100 -> 110011 -> 066660
fun 1  -> fun 2  -> note 1
$ git revert HEAD --no-edit
001100 -> 110011 -> 066660 -> 008863
fun 1  -> fun 2  -> note 1 -> Revert note 1

git flow

好了,基本知識講完了,來說本文重點 git flow
git flow
這什麼意思呢?

  • develop 開發環境會記錄所有 commit
  • release 測試站,階段性完成後測試
  • hotfix 發現穩定版問題,緊急解決,要更新到穩定和開發分支
  • master 穩定,可上線版本,可利用 git tag 標註版號
  • feature 功能分支,會盡可能將 commit 拆小

總歸是,feature, develop 的 每個 commit 會很小,到release 前會整理一次,master 的 commit 範圍最大,現實專案中可能不會用到全部的 branch

如果 dev 不用留下所有 commit 的話會更簡單點,但先示範麻煩的XD

先基本設置

git init
git add . 
git commit -m "init project"
git checkout -b dev

之後增加節點

touch {1..3}
git add 1
git commit -m "one"
git add 2
git commit -m "two"
git add 3
git commit -m "three"

為接合作準備

git checkout -b toBeMerge
git rebase -i master

將 vim 改成

//vim
pick 001100 one
s 110011 two
s 333111 three

離開後跳轉到編輯訊息的 vim

#...
function one

離開後就完成第一步

git checkout master
git merge toBeMerge
git checkout dev
git tag v0.5
git merge feat
git branch -d feat toBeMerge

之後要再開發新功能也是從 dev 開

git checkout -b feat
touch {4..6}
git add 4
git commit -m "four"
git add 5
git commit -m "five"
git add 6
git commit -m "six"
git checkout -b toBeMerge

唯一特別的是

git rebase -i --onto master dev toBeMerge

這段是指,我要把 toBeMerge rebase 到 master 並忽略 dev 已經有的東西,最後將被 rebase 的 bramch 較 toBeMerge
後面就基本一樣

git tag v1.0

最後的 git 會長這樣

summary

好的版控可以讓你的專案井然有條,沒版控的專案及可能會混亂不堪 跟我的人生一樣

English

Time won't stop for anyone, we all facing different choices in our life, but we all wish to travel back in time, to make a different choice in some moment
.
.
.
Do you have the moment you want to change?

It is pity that we can' do over, but we can do our best to leave leave no regrets 7th, May


But!! Git can travel back in time!! Today we gonna discuss git

Structure

  • basic
    • add git into your project
    • git ignore
    • branch
    • commit
    • git rebase and git merge
  • jetbrain ide tool
  • time travel
    • love story in parallel spacetimes
  • git flow
  • summary
  • Reference

basic

use git for version control

create a project, switch to root in terminal, type
git init
to set up git track this folder, we can check it out by ls -a to see .git file

If you want to remove fit, git didn't provide command to undo git init , require type rm -rf .git

git ignore

After initialize, we also get .gitignore
intellij

sample kotlin project

sample web project

It is simple, to declare some file not track by git, we can use glob to define rule

/setting/*.json         # ignore all json file under setting folder
*.txt                # ignore all .txt file

this setting require .gitignore track by git

git add .gitignore
git commit -m "Add git ignore"

After that, you can see ide change color of file from ignored and tracked, usually we will ignore dependency folder and hidden variable

for variable you can use git-crypt as optional

branch

  • Why branch?
    Each branch won't affect each other, and it is basic of git flow
  • How to create a branch?
git branch dev //create dev branch
//or 
git checkout -b feat// create feat branch and checkout
  • How to deal with branch after merged?
    you can keep it, but usually we delete it
git branch -d feat //delete merged feat branch
git branch -D test //delete unmerged test branch

commit

git commit to for other developers to know changed between commits, if your team has format, please follow it, I will share mine

Type:

  • feat -> add/ modify function
  • fix -> fix bug
  • style -> code format
  • refactor -> refactor
  • tests -> add test
  • doc
  • chore -> maintain
  • BREAKING CHANGE
[type] subject

body

fotter

a real sample look like

[feat] : User login

Demand:
 email validate by native rule
 password validate by Regex

Modify:
1. EmailValidator.kt,use Patterns.EMAIL_ADDRESS to validate。
2. PasswordValidator.kt, validate with Regex provided by backend。

Reviewed-by: @Team member
Refs #6

And please describe demand in body

git rebase and git merge

The different between those two is obvious while merge two branch, if dev branch has two branches user, payment

user1 -> user2  
001100 -> 110011 

payment 
090909

By using merge, git will take the result of each branch, check for conflict and create a new commit

//user branch 
git merge payment

user1 -> user2 -> payment -> merge payment into user
001100 -> 110011 -> 090909 -> 686888

By using rebase

//user branch
git rebase payment
payment -> user1 -> user2
090909 -> 776678 -> 899362

git will change commit history, the rebase operator is take commit from user branch to the end of payment branch, and calculate sha value, then point user branch to 889362, Head to user branch

time travel

If your commit already push to remote, only change by revert, reset, rebase will change history, and it will cause problem

reset

Really go back to previous commit

001100 -> 110011 -> 066660
$ git reset HEAD^ --hard
001100 -> 110011

revert

By add a new commit same as 110011, to undo changes in 066660

001100 -> 110011 -> 066660
fun 1  -> fun 2  -> note 1
$ git revert HEAD --no-edit
001100 -> 110011 -> 066660 -> 008863
fun 1  -> fun 2  -> note 1 -> Revert note 1

git flow

Alright, the basic knowledge is done, let's move to the point
git flow
What does that mean?

  • develop -> dev environment record all commit
  • release -> staging
  • hotfix -> if master version has issue, fix it and update to master and dev
  • master -> stable version, using git tag to mark version number
  • feature -> feature branch, all commit here should be as small as possible

In conclusion, each commit in feature, develop will be small scope, commit in master will be the scope between verison, we might not need all branch in reality

If dev branch don't need all commit things will be easy, but let's start will hard one

basic set up

git init
git add . 
git commit -m "init project"
git checkout -b dev

create commits

touch {1..3}
git add 1
git commit -m "one"
git add 2
git commit -m "two"
git add 3
git commit -m "three"

prepare for merge

git checkout -b toBeMerge
git rebase -i master

using vim to change

//vim
pick 001100 one
s 110011 two
s 333111 three

edit commit message

#...
function one

first step done

git checkout master
git merge toBeMerge
git checkout dev
git tag v0.5
git merge feat
git branch -d feat toBeMerge

For more demand, we also create a new branch from dev

git checkout -b feat
touch {4..6}
git add 4
git commit -m "four"
git add 5
git commit -m "five"
git add 6
git commit -m "six"
git checkout -b toBeMerge

the one thing different is here

git rebase -i --onto master dev toBeMerge

it means, I gonna rebase tobeMerge to master and ignore everything exists in dev, then named to branch toBeMerge

others are same

git tag v1.0

the result will look like

summary

Good version can make your project clean,

Reference

git-scm
為你自己學 Git
伸縮自如的 Git flow
write better commit message


上一篇
Day 9 程式碼保衛戰 Defensive programming
下一篇
Day 11 OO 能吃嗎? 繼承與調香技法 inheritance
系列文
Kotlin on the way31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言