---
# System prepended metadata

title: 版本控制 Git
tags: [2023 軟體培訓]

---

# 版本控制 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