###### tags:`github`
# 分散式版本控制系統 git & gitHub
## 分散式版本控制系統的優勢
* Git可以把檔案的狀態作為**更新歷史記錄保存**起來。因此可以把編輯過的檔案復原到以前的狀態,也可以顯示編輯過內容的差異。
* 在Git管理檔案的話,更新歷史會保存在Git。所以**不需要複製備用的檔案**啦。
* 而且,當有人想將編輯過的舊檔案上傳到伺服器、**覆蓋**其他人的最新檔案時,**系統會發出警告**,因此**可以避免在無意中覆蓋**他人的編輯內容。
<br>
## 使用數據庫管理歷史記錄
**數據庫 (Repository)** 是記錄檔案或目錄狀態的地方,儲存內容的修改歷史記錄。在數據庫的管理下除了儲存修改歷史記錄外,還可以追蹤內容的狀態和版本

如果想要公開在本地端數據庫的修改內容,就需要將內容上傳到遠端數據庫了。另外,透過遠端數據庫還可以取得其他人修改的內容。

### 建立本地端數據庫的方法
建立本地端數據庫的方法有兩種:一種是重新建數據庫。另一種是複製遠端數據庫。

### 記錄修改的提交
若想把變更與新增的檔案/目錄儲存到數據庫中,您需要執行提交(Commit)。
執行提交後,數據庫裡會產生上次提交的狀態與現在狀態的差異記錄(也被稱為Revision)。
提交是以時間順序排列狀態被儲存到數據庫中的。憑藉該提交和最新的檔案狀態,就可以知道過去的修改記錄以及內容。

為了區分提交,系統會產生一組識別碼來給提交命名,識別碼會根據提交修改的內容計算出不重複的40位英文數字。指定識別碼,就可以在數據庫中找到對應的提交。
>像錯誤修復或功能添加之類<font color="blue">**不同含義的更改**</font>,要盡量<font color="blue">**分開來提交**</font>。這樣可以方便事後從歷史記錄裡找出特定的修改內容
執行提交時,系統會要求輸入提交訊息。請<font color="blue">**務必輸入提交訊息**</font>,因為在訊息空白的狀態下執行提交是會失敗的。
>提交訊息是查看其他人提交的修改內容或自己檢查歷史記錄時重要的資料。所以要用心填寫讓人容易理解的提交訊息。
Git的**標準提交訊息**:
```
第1行:提交時修改內容的摘要
第2行:空行
第3行以後:修改的理由
```
### 工作目錄與索引
**工作目錄(Working Tree)** 是保存您目前正在處理檔案的目錄,**Git** 相關的操作都會在這個目錄下完成。
**索引(Index )** 位於工作目錄和數據庫之間,是為了向數據庫提交作準備的暫存區域。

所以在**工作目錄上做的任何變更**並<font color="red">**不會直接提交到數據庫**</font>的。**Git在執行提交**的時候,不是直接將工作目錄的狀態儲存到數據庫,而是<font color="red">**將索引的狀態儲存到數據庫**。</font>因此,<font color="red">**要提交變更,首先必需要把變更內容加入到索引中**。</font>
**索引的存在**可以<font color="blue">**排除工作目錄裡不必要的檔案提交**</font>,還**可以只將檔案變更內容的一部分加入索引並提交**。
## 共享數據庫
### 推送到遠端數據庫:Push
為了將本地端數據庫的修改歷史共享到遠程數據庫,必須上傳本地端數據庫中儲存的修改歷史。
為此,需要在Git執行**Push(推送)操作**。執行Push之後,本地端的修改歷史會被上傳到遠端數據庫。遠端數據庫的修改歷史就會和本地端數據庫的修改歷史保持同步。

### 複製遠端數據庫:Clone
如果遠端數據庫中有其他人的修改歷史,那麼把它完整地複製下來。執行 **複製(Clone)** 後,可以把遠端數據庫裡的內容全部下載下來,之後您可以在另一台機器的本地數據庫上進行操作。
>修改歷史也會被複製到本地數據庫裡,所以和原本的數據庫一樣,可以查看歷史記錄和提交了。
### 從遠端數據庫執行拉取:Pull
若是**共享的遠端數據庫由多人同時作業**,那麼作業完畢後所有人都會把修改歷史push到遠端數據庫。所以**需要同步其他人push的修改內容到自己的本地端數據庫**。欲**同步遠端數據庫以更新本地端數據庫**,請使用**Pull(拉取)**。執行pull之後,會從遠端數據庫下載最新的修改歷史,將其同步到自己的本地端數據庫。

### 合併修改記錄
您上次的push到執行下一次的push的期間,如果有其他人push更新了遠端數據庫,而您沒有更新您的本地端數據庫,那麼您的push會被拒絕。

### 解決衝突
如果遠端數據庫和本地端數據庫的同一個地方都發生了修改的情況下(例:檔案中同一行的地方)。
這時,因為Git不能自動判斷要導入那一個修改內容於是就會發生錯誤。

## 基本 command 與 git command 指令指令
<!-- github
https://github.com/38net/LINAMERICA
-->
:::info
## DOS command
:::
0.切換至硬碟:硬碟名稱: (ex: C>F:)
1.移動路徑:cd 路徑
2.回上一層:cd .. PS:是兩個.. 不是一個 .
3.展開列表:dir
4.開新資料夾: md 資料夾名稱 (ex: md show)
5.開新檔案: cd.>檔案名稱 (ex:cd.>index.html)
***
:::info
## Git command
:::
1.移動路徑:cd 路徑
2.回上一層:cd .. PS:是兩個.. 不是一個 .
3.展開列表:ls
4.開新資料夾: mkdir 資料夾名稱 (mkdir md show)
5.開新檔案: touch 檔案名稱 (ex:touch index.html)
***
:::info
## Git 基礎設定
:::
1.git config --global user.email "gonsakon@gmail.com"(輸入姓名)
2.git config --global user.name "gonsakon"(輸入email)
3.git config --list (查詢設定列表看看是否成功)
4.git version(查詢版本 )
***

:::info
## Git 新增本地/遠端數據庫
:::
在本地資料夾新增數據庫
git init<br>
複製遠端數據庫
git clone 遠端數據庫網址
***
:::info
## Git 增加/刪除檔案(工作目錄-->索引-->本地數據庫 Local Repository)
:::
git add 檔案名稱 (增加檔案進入索引)
git add .(增加全部檔案進入索引,注意add跟.之間有空一格!!)<br>
git status(查詢狀態)<br>
git log(顯示歷史紀錄)<br>
git commit -m '更新訊息'(將索引提交到數據庫,即進入版本控制)
***
:::info
## 忽略檔案 gitignore
:::
* 使用 .gitignore (忽略檔案)
* 在.gitignore檔案中使用*.html(忽略所有副檔名為html的檔案)
* 在.gitignore檔案中使用folder名稱/(忽略整個folder)
***
:::info
## Git 還原指令(取消與還原)
:::
### 取消索引的方法
把提交到索引的檔案取消,讓其回到工作目錄上
git reset HEAD 檔案名稱(單一檔案取消索引)
git reset HEAD (取消目前在索引上所有的檔案)
### 還原檔案的方法
git checkout 檔案名稱(恢復單一檔案到最新的commit 狀態)
git reset --hard (還原工作目錄與索引,會跟最後一次commit的狀態保持一致)
git reset --hard HEAD^ (刪除最近一次 commit )
git reset --hard ORIG_HEAD (上面語法如果刪除錯了可以再用此語法還原)
git reset --soft HEAD^ (刪除最近一次 commit,但保留異動內容)
git commit --amend (commit 後發現有幾個檔案忘了加入進去,想要補內容進去時)
***
:::info
## Git 分支
:::
git branch(顯示所有本地分支)
git branch 分支名稱(新增分支)
git checkout 分支名稱(切換分支)
git merge 分支名稱(合併指定分支到目前的分支)
git branch -d 分支名稱(刪除分支)
***
:::info
## 標籤
:::
查詢標籤
git tag
查詢詳細標籤
git tag -n
刪除標籤
git tag -d 標籤名稱
新增輕量標籤
git tag 標籤名稱
新增標示標籤
git tag -am "備註內容" 標籤名稱
***
:::info
## 暫存
:::
暫時儲存當前目錄
git stash
瀏覽 stash 列表
git stash list
還原暫存
git stash pop
清除最新暫存
git stash drop
清除全部暫存
git stash clear
***
:::info
## 遠端數據庫操作
:::
複製遠端數據庫
git clone 遠端數據庫網址
查詢遠端數據庫
git remote
將本地分支推送到遠端分支
git push 遠端數據庫名稱 遠端分支名稱
將遠端分支拉下來與本地分支進行合併
git pull
將遠端分支拉下來,但先不與本地分支進行合併
git fetch origin(遠端數據庫) branch1(遠端分支)
(此時你的分支會多一個 FETCH_HEAD 的分支,這個就是遠端數據庫的分支,可以等到你看過沒問題後,再下 git merge合併 FETCH_HEAD 也 ok。)
***
:::info
## Git 儲存帳號、密碼
:::
不想每次執行都要打一次帳號與密碼,有下列方式:
### 讓 git 自動將帳號與密碼儲存起來
```txt
設定自動儲存帳號與密碼
git config --global credential.helper store
```
接著執行任何一個需要帳號與密碼的 git 指令(例如 push 或 pull 等):
```txt
下載更新內容
git pull
```
### 修改帳號或密碼
方法一:
當輸入完帳號與密碼之後,git 就會自動將這一組帳號與密碼儲存至 ~/.git-credentials 這個設定檔中,若需要修改帳號或密碼,可以直接從這個檔案來修改,而這個檔案的權限只有自己能夠讀取。
方法二:
直接將 ~/.git-credentials 這個檔案刪除,再重新執行一次需要帳號與密碼的 git 指令,讓 git 重新建立該設定檔。
### Git 暫存帳號、密碼
如果因為安全性考量,不希望將帳號與密碼儲存在硬碟中,可以改用 cache 模式,讓帳號與密碼自動儲存在記憶體中(維持 15 分鐘):
```txt
設定自動暫存帳號與密碼(存在記憶體 15 分鐘)
git config --global credential.helper cache
```
git 就會自動將帳號與密碼暫時存放在記憶體中 15 分鐘,在這段時間之內,當 git 需要帳號與密碼時,就會直接使用這個暫存的帳號與密碼,不需要再次輸入。
如果要自訂帳號與密碼的暫存時間,可以用 --timeout 參數指定時間(單位為秒),例如將暫存時間設定為一小時:
```txt
帳號與密碼暫存一小時
git config credential.helper 'cache --timeout=3600'
```
### Mac 鑰匙圈存取
若在 Mac 的系統上,也可以使用 Mac 內建的鑰匙圈存取功能來存放 git 的帳號與密碼,讓系統統一進行加密保護:
```txt
設定自動儲存帳號與密碼(Mac 鑰匙圈存取)
git config --global credential.helper osxkeychain
```
### 申請個人 token
[創建個人訪問令牌教學](https://docs.github.com/cn/github-ae@latest/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)
### 使用 SSH 連接/上傳到 GitHub
[使用 SSH 連接/上傳到 GitHub 教學](https://israynotarray.com/git/20210709/1381487661/)
***
:::info
## 分支觀念
:::
[文章來源:A successful Git branching model](https://nvie.com/posts/a-successful-git-branching-model/)


***
:::warning
## 相關網站
:::
[連猴子都能懂得 Git 入門指南](https://backlog.com/git-tutorial/tw/)
[保哥 30 天 Git 教學](https://github.com/doggy8088/Learn-Git-in-30-days/blob/master/zh-tw/README.md)
[Git 官方繁體教學](https://git-scm.com/book/zh-tw/v2/%E9%96%8B%E5%A7%8B-Git-%E5%AE%89%E8%A3%9D%E6%95%99%E5%AD%B8)
**安裝Git**
[Windows(GUI)-TortoiseGit](https://backlog.com/git-tutorial/tw/intro/intro2_1.html)