---
# System prepended metadata

title: Git 版本管理
tags: [git]

---

###### tags: `git`
# Git 版本管理
    當一個工程師先問問自己該如何管理程式碼？
    工程師該如何交流程式碼？
    
    用途：
        管理程式碼
        交流程式碼
        新版程式出現錯誤，版本控制系統也還原至舊版（切換版本）
        上傳到雲端版本控制服務平台（GitHub）
        利用分支同時開發不同功能
        
## 分支與合併
![](https://i.imgur.com/ZqjKvEw.png)

    master 表示穩定版本
    其他的分支表示開發新功能（可以同時進行）
    開發成功後才合併回 master

## git & github 差異
* Git : 分散式"版本控制"軟體。
* Github : 支援 git 程式碼存取和"遠端托管儲存庫"的平台服務 
* git Repository : 儲存庫、數據庫
* Github : 只能放數據庫
    


## 軟硬體
* macbook air
* macOS 10.15

## 查看 git 是否安裝成功
```
  git --version
```
## 操作步驟
> 步驟一：[下載 git](https://git-scm.com/downloads)
 [下載 Homebrew](/@wallet69/homebrew) 可以集中管理套件
  步驟二：建立一個要做版本管理的資料夾
  步驟三：開啟終端機
  步驟四：把當前目錄調到這個文件夾 (ex.cd downloads)
  步驟五：記錄每一個修改檔案的人

```
  git config --global user.name "wallet69"
  git config --global user.email "wallet@gmail.com"
```  
> 查詢使用者名稱及電子郵件是否設定成功
```
  git config --list
  git config user.name
  git config user.email 
```
> 步驟六：對專案註冊 Git 版本控制
```
  git init
  
```

mac 用 command + shift + . 顯示隱藏檔案會看到 `.git` folder
> 步驟七：列出所有文件
```
  ls
```
> 步驟八：建立一個新文件（文件存在工作目錄中，尚未加入數據庫）
```
  touch 檔案名稱
  touch 1.py
```
> 步驟九：查看版本庫的狀態
```
  git status  #狀態全寫
  git status -s # 狀態縮寫 
```

:::info
git status 只顯示和上一個 commit 不同的部分
:::
> 步驟十：將檔案加入索引
```
  git add 檔案名稱
  git add 1.py
  git add . # 將所有檔案加入索引
```

> 步驟十ㄧ：提交一個檔案的新版本
```
  git commit -m "<填寫版本資訊>"
```
![](https://i.imgur.com/btA5gF5.png)



> 步驟十二：查詢所有更改版本的訊息
```
  git log
```
## git 中檔案的各個狀態
![](https://i.imgur.com/hKvG14n.png)

## diff 不同形式
> 在 unstaged 狀態和先前 commit 狀態的檔案差別
```
  git diff 
```

> 在 staged 狀態和先前 commit 狀態的檔案差別
```
  git diff --cached
```

> staged & unstaged 狀態和先前 commit 狀態的檔案差別
```
  git diff HEAD
```

## 修改已 commit 的版本 
> 已經commit的版本，忘了附上另一個文件(2.py)，但不想增加一個版本
> 版本資訊不會改變，但 id number 會變
```
  git add 2.py
  git commit --amend --no-edit  #修正不編輯，直接合併 
  git log --oneline 
```
> git log --oneline(看到當前變化)
![](https://i.imgur.com/pn9gnkM.png)
## reset (不可以隨便亂用，可能會造成不可還原的影響)
### 從 staged 回歸 unstaged
```
  git reset 1.py
```

### 回到過去各種版本
> 藉由 HEAD 指標的移動更換目前版本
![](https://i.imgur.com/7yDI3u5.png)
### 回到上一個 commit版本
    git reset --hard 表示不保留工作目錄中的檔案
```
git reset --hard HEAD  #上一個
git reset --hard HEAD^ #上上個
git reset --hard HEAD~2 #上上個
git reset --hard "id number"  #回到指定id 的版本
```
> 黃色字串為 id number
![](https://i.imgur.com/pn9gnkM.png)

### 看到過去每一步的變化並更換版本
```
  git reflog
``` 
> 此時的 git reset --hard 後面可加入 id number 或是 HEAD@{x}
> ![](https://i.imgur.com/qCirQre.png)
```
  git reset --hard "id number"
  git reset --hard "指標"
```

### 檔案已加入索引，退回工作目錄
```
  git reset HEAD
```
## git 新增遠端數據庫
* 前往 github 網站
* 註冊會員 or 登入會員
* 右上角有一個 "+" 的符號
* 按下 new repository 
* 輸入一個專案名稱
* 在終端機中 cd 到你想遠端分享的檔案
* 輸入 git remote add origin ...(到.git/config 檔案中確認是否成功遠端分享)
* Mac: command + shift + . （dot）顯示隱藏檔案/檔案夾(.git)
![](https://i.imgur.com/Yd82PRB.png)
* 輸入 git branch -M main
* 輸入 git push -u origin main
* 若發生錯誤，解決方法如下：
>   修改 [remote “origin”]  
    url = https://github.com/xxx/example.git  
    [remote “origin”]  
    url = https://xxx@github.com/xxx/example.git  
    再次git push，即可提交

    
## git 縮寫
> 用 co 代替 checkout
```
  git config --global alias.co checkout
```
> 這個功能會存放在 使用者/.gitconfig 中，可以直接在這個檔案內修改


## 測試主機與正式主機
![](https://i.imgur.com/cetnUHs.png)
> 當程式碼在本地端完成時，會先放到測試主機上運行，再放到正式主機上
> git remote add 因為還沒有 push ，所以一開始 0 commit
> -u 表示預設會推到哪個遠端數據庫
> git push 會推到預設的遠端數據庫
```
  git remote add origin ... (先前的 origin 表示正式主機)
  git remote add test  ... (test可自訂名稱 表示測試主機)
  git push -u test main #先 push 到測試
  git push -u origin main #再 push 到正式
```
![](https://i.imgur.com/nxSPrTO.png)


## checkout 指令
> 表示把 HEAD 指標指向某ㄧ個 commit 
> git checkout 代碼(可以打幾個字後按tab鍵，git會自動補齊代碼)
> 資料夾會出現當時的檔案（與最新的 commit 不同）
> git checkout main 可以回到最新版本的 commit
> git checkout -- file name 刪掉還未進入索引的步驟


## 清空還沒被追蹤的檔案
> 測試階段創建的檔案可以一次清除
```
  git clean -n #查看會刪掉的檔案
  git clean -f #強制刪除檔案
```

## branch 分支
> 預設的分支是 main

### 創建分支
```
  git branch branch名稱
  git branch develop
```

### 查詢分支
```
  git branch
```

### 刪除分支
```
  git branch -d branch名稱
```

### 在多個分支中轉換 HEAD
```
  git checkout branch名稱
```

### 合併
> 當 develop 測試成功後
> 將 main 和 develop 合併
```
  git checkout main
  git merge develop #預設快轉 (只有一條分支)
  git merge --no-ff #取消快轉 (有兩條分支)
```
## git branch 練習

https://learngitbranching.js.org/?NODEMO=&locale=zh_TW


## 參考資料
> [參考資料](https://tw.alphacamp.co/blog/git-github-version-control-guide)



## 將 git 的預設編輯器更改為 Vim
```
  git config --global core.editor "vim"
```

> ZQ : 結束 vim 的方式


## 發 PR (pull request)
1. 看到自己喜歡的專案 fork 那個專案
2. 發現那個專案有小問題要修改 
3. 下載專案 git clone github給的網址
4. 在 master 上新增一個 commit 
5. 對該專案作者發 pull request
6. 作者認為可以提升專案完整度則 merge 了 PR



## git merge 衝突
> 當你在不同分支中修改到同樣的 code 會產生衝突
> 在 visual studio code 可以直接選擇要保留哪一個 code
> 修改完才能正常合併
> 有衝突的檔案會先放到工作目錄上
> 解決衝突後需先 git add 再 git commit


## git pull
> 合併遠端數據庫分支的修改內容
> 當我們不知道 server 上的 code 已經更新，就直接使用 git push 就會被 server 拒絕