# 版本控制 Git ## 什麼是 Git? 分散式版本控制系統 ![](https://hackmd.io/_uploads/HJTRNG0W6.png) ### 為什麼要用 Git? - 版本控制 - 多人協作 - 分支 ### Git vs. Github 簡單來說,Git 是一種版本控制工具,Github 則是一個用來託管 Git repository 的平台 ![](https://hackmd.io/_uploads/HJ1eLf0Z6.png) ## Git 概念 ### Repository 儲存source code與變更歷史,通常一個專案會用一個repository儲存。 在一個repository中,變更歷史被存在`.git`這個資料夾裡面。 ### Commit git控制版本的最小單位,一個repository的變更歷史由一連串的commit組成。 其中一個commit包含但不限於: * **changes**: 紀錄這個commit對專案的改動 * **commit message**: 說明這個commit做了哪些事情 * commit id * author name * author email ### Local vs Remote Repository 在使用git進行開發的過程中,我們通常會在自己的裝置上放一個repository進行程式的編輯,這個repository就叫做**local repository**。 而為了將專案進行備份與協作,我們會將repository放到伺服器(Github)上,這個repository就是**remote repository**。 ### Pull & Push 當remote和local其中一方更新時,另外一方並不會即時更新,需要我們手動更新。其中將remote的變更更新到local的這個動作叫做**Pull**,反過來將local的變動更新到remote是**Push**。 ### Branch 在進行多人開發時,為了避免版本之間的衝突,當想要為專案作一項變動時,通常會新增一條新的branch(分支),完成一連串變更後,再merge(合併)回原分支。 然而當我們在一條branch進行開發時,main branch(專案的主要分支)也可能會經過變動,此時直接merge的話就會發生版本衝突,需要解決完衝突才能完成merge。因此若是main branch的版本太新,通常會先將main branch merge到自己新增的這條branch,再merge回去main branch。 ### Pull Request 前述將branch merge回main branch的這個動作,在github上的操作被稱為Pull request。這個步驟被用來讓其他專案成員review這項更新並選擇是否接受。 ## 安裝與設定 使用 apt 安裝 git: ``` sudo apt install git ``` 設定使用者資訊: ``` git config --global user.name "your_name" git config --global user.email "your_email" ``` 設定 github SSH key: ``` ssh-keygen cat ~/.ssh/id_rsa.pub ``` ![](https://hackmd.io/_uploads/HkqvlVgWT.png) ## 常用指令 ### 初始化 git repository 自己建立新的 repository ``` git init git remote add <name> <url> ``` 或是從遠端 (e.g. github) clone ``` git clone <url> # e.g. git clone git@github.com:NCTU-AUV/sauvc_sim.git ``` ### 查看 git 相關紀錄 ``` git status ``` ``` git log ``` ### Git 工作流程 ![](https://hackmd.io/_uploads/SybGhXgbp.png) #### add 加入暫存區 (staging area, index) ``` git add <file> ``` #### commit commit 到 local repository ``` git commit ``` - 每筆 commit 應該越簡單越好 - how to write commit message: https://www.conventionalcommits.org/en/v1.0.0/ #### push push 到 remote repository ``` git push <remote> <branch> ``` ## 分支 (branch) ![](https://hackmd.io/_uploads/BybDyExWp.png) ### branch 查看現有的 branch ``` git branch ``` ### switch 切換 branch ``` git switch <branch> ``` ### merge 合併 branch ``` git merge <branch> ``` ### rebase 從某一筆 commit 後 重新 apply commits ``` git rebase <commit> # e.g. git rebase master ``` ![](https://hackmd.io/_uploads/H1VvGVlba.png) ## GUI ### VSCode Extensions #### Gitlens ![](https://hackmd.io/_uploads/HyUPeRPW6.png) #### Git graph ![](https://hackmd.io/_uploads/r1etxAvWp.png) ## References