# Blog 1|深入淺出 GIT 第一篇來介紹一下 GIT,我第一次開始認真學習並且使用 GIT 技術,也是研究所畢業後的事情,在面試找到工作後到職日前,把 GIT 的網路上教程好好惡補一下 XD 以前在學校只有使用基本的 git add -> git commit -> git push 而已,說來其實有點慚愧,認真去了解後會發現 GIT 的許多設計都很有哲理,GIT 的有些指令或許有些複雜,其實只需要掌握一些基本原則,是一個非常容易使用且方便的版本管理工具 ### **(1) GIT 基本操作** Git 在把改動打包成 commit 的時候,需要經過兩個步驟 - ```git add``` : 把改動放到暫存區 - ```git commit``` : 把暫存區的改動用 commit message 包成一個 commit 暫存區的概念和這兩個步驟,看起來會有些複雜,但了解後其實是很方便且貼心的設計。有時同時有非常大量的改動,全部包成一個 commit 可讀性是很差的,不好 code review 日後也會很難追蹤,這種兩階段的機制能夠很好管理,每一個 commit 需要包含哪些部分。  ### **(2) GIT branch 的使用** 使用 GIT 時,有一個基本但非常實用的功能是 branch。在 GIT 中,`branch 是一個指向 commit 的 pointer`,他被放在目錄 ```.git/refs/heads/``` 當中,因此新增/刪除/切換 branch,都是非常快速且輕量化的操作。 透過 ```git checkout [-b] <branch_name>```,我們可以快速於不同任務當中切換。  ### **(3) GIT reset v.s. revert** 當把改動打包成 commit 後,有時後悔想要拆除,就要使用 reset 或是 revert 指令。 - ```git reset``` 會真的把 commit 拆除掉,又分成三類 - (1) ```git reset --soft <commit_id>``` : disk 和 staging 仍會有該改動 - (2) ```git reset --mixed <commit_id>``` : disk 仍會有該改動 - (3) ```git reset --hard <commit_id>``` : 該改動全部被移除 - ```git revert``` 則是會建立一個和原改動相反的 commit 這兩個指令要視情況使用,原則上想要拆除剛建立的 commit 並保持整體改動歷史乾淨,會選擇 ```git reset``` 重新打包才對。而若是已將該 branch 推送到遠端的 repository,或是想要很明確在改動歷史中,知道曾經有這個 change 但後來決定要移除,就會選擇 ```git revert```。 這兩種做法還有一個差異,關於是否可以直接撤銷遠端上方的 commit,使用 revert 的方式可以直接 ```git push``` 更新遠端,但若是 reset 的方式要使用 ```git push -f``` 來更新。 ### **(4) GIT merge v.s. rebase** 在使用 branch 開發功能完畢後,需要把這個 branch 上的改動 merge 回主分支,這時候可以分成 merge 或是 rebase 兩種操作。 - ```git merge``` : 建立一個新 commit 同時指向兩個 branch - 若方向為 A merge B,則 A 這個 branch 會被指到最新建立的 commit 上,B 保持不變 - ```git rebase``` : 將我這個 branch 上獨有的 commit,一一搬移到對方 branch 上 - rebase 常被用來增加改動歷史的可讀性 ### **(5) 一個常見的協作流程** 這裡介紹一種最常用、最好用,團隊共同使用 gitlab 來開發的方法。 - (1) 將 gitlab 上的 ```git clone``` 回本地,其中主分支為 ```main``` branch - (2) 使用 ```git checkout -b my-feature``` 切換到開發分支 - (3) 開發並打包 commit,透過 ```git add``` 和 ```git commit``` - 在 push 回 gitlab 前,假設有其他人也同時更新 gitlab 上的 ```main``` branch - (4) ```git checkout main && git pull origin main```,把 gitlab 上的 ```main``` branch 同步回本地 - (5) ```git checkout my-feature && git rebase main```,整理除了 ```origin/main``` 之外的額外改動 - (6) ```git push origin my-feature```,將 ```my-feature``` 推送到 gitlab 上 - (7) 於 gitlab 的網頁上,使用 Merge Request 按鈕,發送一個 merge 的請求 - (8) 於 gitlab 的網頁上 Code Review,檢查是否可合併,或是有些工具可把改動拉回本地 - (9) 於 gitlab 的網頁上,Merge - (10) 清理 Gitlab 和本地中的 unnecessary branch  ### **(6) GIT FLOW** 這裡參考 [A-successful-git-branching-model](https://nvie.com/posts/a-successful-git-branching-model/),節錄一些要點 - 相比於其他 version control 工具,git 中的 merging/branching 都十分 cheap 且 simple - Git 本質去中心化,但可以中心化式管理 - 兩條主分支 (Master, Develop) - **Master** : 處於 **production-ready** 的狀態,只有在完成 release 與 hotfix 後,才會變動 - **Develop** : 開發用主線,所有對於需求的新增、修改、測試都在此分支。開發完成後才會用 release 與 master 進行同步 - 三條支援分支 (Feature, Release, Hotfix) - Feature : 由 develop 分離,一次開發一個功能,完成功能開發後就會 merge 回 develop - Release : 當預定的功能都開發完成時,會開一條前綴為 release 的分支,完成後 merge 回 master 與 develop - HotFix : 當交付的軟體回報有問題時,會開一條前綴為 hotfix 的分支,完成後 merge 回 master 與 develop  ### GIT 和 Perforce 的比較 我目前所在的公司,是使用 perforce 作為版本控制工具,真心覺得不是很好用。一樣為版本控制工具,perforce 是 1995 年被創立的,而 GIT 是 2005 年首度發布。兩套工具的社群和使用人數有非常顯著的不同,特別值得一提的是 perforce 只有商業版,一般使用者是沒辦法在自己的環境去練習 perforce 的操作的,而 GIT 有以 GNU GPL 開源授權,光是這一點就很好去做選擇了。 底下列出一些使用 perforce 上的痛點 - Perforce 沒有 branch 來多工處理不同任務 - 若要同時處理不同 issue,需要同時開多個目錄,sync sandbox 回本地 (類似 git clone) - 浪費 disk 空間,也浪費 syncing 的時間,開發上也不容易切換 - Perforce 的 ChangeList 是以檔案作為單位 - 一次 checkin/code review,只能以檔案為單位,看改動前後的差異 - 不支援在一次 code review 中,用 commit message 把改動拆成更小單位 - 不支援在一次 code review 中,對一個檔案 partial commit - 同一個 sandbox 只能 shelve 一個改動 - git 能夠於本地端暫時打包成 commit - git stash 可以存多個改動 - 對任何檔案操作前,都需要事先 "p4 add/edit/delete <path_to_file>"
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up