# Github 教學
[toc]
## 基本指令
- 安裝, 實際步驟
1. ``sudo apt install git``
2. `git init`
3. ``ssh-keygen -t rsa -C "youremail@mail.com"`` # 填 email
4. 回到github,進入Account Setting,左邊選擇SSH Keys,Add SSH,title隨便填,貼上 `.ssh/id_rsa.pub` 的 key.
5. 驗證是否成功<br/>``ssh -T git@github.com``
6. 加入專案<br/>``git remote add origin https://github.com/USER/REPO.git
``
- 更新 user
- `git config --global user.name ""`
- `git config --global user.email ""`
- 更新
-> cd 到要更新的目錄
-> git add .
-> git commit -m '做了哪些更動' (取好一點名字, 方便之後找)
-> git push origin master(branch name)
- 找 branch name
-> git branch -m
- 修改要放的 repository 位置g刪除目前位置
-> git remote rm origin
加入要去的位置
-> git remote add origin url(repository 的 ssh 網址)
- 回溯 commit
- 找出 commit 的代號
-> git log --online --graph
找出那次 commit 更改哪些, 會把更改的檔案的東西全印出
-> git show x(代號)
- 查前 n 次 : `git diff HEAD~n`
- ex. `git diff HEAD~1`
- 查詢現在使用的 git user
-> git config --global user.name
設定名字
-> git config --global user.name "tommy"
- error : Please make sure you have the correct access rights
改成 https
git remote set-url origin https://github.com/
- 推不上去
1. git pull origin master --rebase # 使用 Rebase 方式合併
2. git push origin master -f (不建議,會把之前的 commit 都洗掉)
- error : remote: Support for password authentication was removed
settings -> developer settings -> personal access token -> fine-grained token -> 給權限後得到 ssh token -> password 輸入 ssh token
- 查看分支 : `git branch` 、 `git branch -r`
- 建分支 : `git branch new_branch_name`
- 換分支 : `git checkout new_branch_name`
- 檔案內容會被直接換成該分支
- 複製特定分支 : `git clone -b develop --single-branch https://github.com/tommygood/imCredit.git`
- commit 前查看這次新增修改了甚麼
- `git add .`
- `git status`
- 查看 remote 分支和本地的不同
- 先看一下本地有沒有 remote branch
- 若無就 `git fetch`
- ex. 查看和 main 分支的不同 : `git diff main`
- readme
- 通常會有的欄位
- background
- intertroduce
- installation
- usage : 使用方法
- script tag 無法顯示的問題
- 要隔一行
- ex. 
- 刪除檔案的快取
- `git rm --cached file_name`
- 一開始為 master branch
- 一開始 pull 下來預設都是 master branch,所以如果 repo 是 main branch 或其他 branch 就要注意
- 可以把本地的 master branch 對到 remote 的 main
- `git push origin master:topic`
- 合併發生衝突 : `Automatic merge failed; fix conflicts and then commit the result.`
- 原因
- 因為相同檔案的相同行被不同人更改,且他們相同 branch 的 commit history 不同
- 範例
```html=
<div class="container">
<<<<<<< HEAD
<div>我是 Cat</div>
=======
<div>我是 Dog</div>
>>>>>>> dog
```
- 解法
- 把要保留的留下來,不要的刪掉,再推一次
```html=
<div class="container">
<div>我是 Cat</div>
```
- `git add .`
- `git commit -m "fixed merge~"`
- `git push xxx`
- ref
- https://gitbook.tw/chapters/branch/fix-conflict
- 抓遠端分支 : `git fetch`
- 再 `git switch xxx` 就可 switch 到 xxx branch
- 刷新新增內容 : `git reset`
- `錯誤: 您對下列檔案的本機修改將被合併動作覆蓋`
- 可以用 `git restore` 把改過的檔案還原
- `警告:您正丟下 1 個提交,未和任何分支關聯`
- 幫這個 commit 建一個 new branch : `git branch {commit_id} {new_branch_name}`
- 切換回原本的 branch : `git checkout master`
- merge 兩個 branch : `git merge {new_branch_name}`
- 更改 commit user
- `git commit --amend --author="krixi <annnn6633@gmail.com>"`
## learning
- git add `file_name`
- 將 file 加入 stage (暫存區
- if `file_name` == `.` : 把當前目錄所有檔案加入暫存區
- `-p` : 逐個區塊問你要不要 add 到 stage
- git commit -m "msg"
- 將 stage 的 file 修改的內容提交到當前 branch
- 可在本地 commit 多次再 push 上去 remote
- `git push origin branch_name`
- `origin` : repo 來源的名稱(也可改別的)
- 
- 設定 `upstream` 後可直接 `git push`
- `git push -u origin {branch_name}`
- 或是 `git push origin {branch_name}`
- 之後就 push 就可以直接 `git push`
- `git push origin master` 在幹嘛 ?
- 
- `git status`
- check 和上次 commit 不同部分
- 
- 
- `git log`
- 看本地端目前有的 commit 紀錄
- 
- 看 remote 的 commit
- 先抓 remote commit : `git fetch`
- 將 remote 的新 commit 抓到 local
- 再看 remote commit : `git log origin/master`
- 
- `git log --oneline`
- 比較好閱讀
- `git fetch`
- 抓 remote 的 branch 的新 commit(還沒 merge)
- `git fetch`
- 假設 remote 的 branch 上多了一個 commit
- 
- 看遠端和本地的 branch 的 commit 的差別 : `git log {remote}/{branch}`
- 
- 看本地和遠端的新的 commit 的內容的差別 : `git diff {remote}/{branch}`
- 
- 將本地的 branch 合併遠端的
- `git merge {remote}/{branch}`
- 
- 本地和遠端的 commit 就會相同
- 
- `git pull origin branch_name`
- = `git fetch` + `git merge`
- `HEAD`
- 指向目前在哪一個 commit
- 
- `detached HEAD` : `HEAD` 指向沒有 branch 的 commit
- 
- 當 checkout 到沒有 branch 指向的 commit 就會發生
- 因為一個 branch 會指向一個 commit
- 
- 所以這邊可以切到沒有 branch 指向的 commit : `git checkout 07a79ee`
- 
- ex.
- 一開始, head 指向 master branch
- 
- 切到之前的 commit : `git checkout cd82f29`
- 
- 也可以在這個 detached head 狀態下 commit(但此時新的 commit : `b6d204e` 沒有 branch 指向他)
- 
- 但若 checkout 回別的 branch,此 commit 就不易找到,所以會幫這個 commit 建一個新的 branch 就可以了
- `git checkout -b {new_branch}`
- 
- 所以如果想要回到某一個 commit 再建新功能
- 一開始在 main branch 有幾個 commit(目前 HEAD 在 main 的 branch 指向的 commit,也就是 c4)
- 
- 回到 c1 這個 id 的 commit
- `git checkout c1`
- 或是回到 HEAD 的 3 個 commit 前
- `git checkout HEAD~3`
- `git checkout HEAD^^^`
- 或是回到 main 的 3 個 commit 前
- `git checkout main~3`
- `git checkout main^^^`
- 
- 在 c1 的狀況下開新功能
- 幫這個 commit 建一個 branch : `git checkout -b new_func`
- 
- 在 `new_func` 的 branch 新增功能,加 2 個 commit(c5, c6)
- `git commit -m "new1"`
- `git commit -m "new2"`
- 
- 新增完功能了,把新的 commit 整合回 main branch
- `git rebase main`
- 
- 把 main branch merge new_func merge
- 先切回去 main : `git switch main`
- 再 merge : `git merge new_func`
- 
- 若有 conflict 就須先解決才能 merge
- ref
- https://gitbook.tw/chapters/faq/detached-head.html
- `git branch`
- 查看目前分支
- `-r` : remote branch
- branch 會指向一個 commit 的 reference
- 
- 建立 branch 過程
- 
- 
- 改變 branch 指向的 commit
- 原本
- 
- 改到 c6 這個 commit : `git branch -f c6`
- 
- `git checkout`
- 可以 restore 檔案、切換 commit(<b>切換 HEAD,不切換 branch</b>。所以 branch 還在相同 commit)、切換分支,但若是檔案和分支同個名字會優先做切換分支,但若是想要 restore 檔案就會有問題,所以後來拆分開來 :
- `git restore` : 還原
- `git switch` : 切 branch
- 通常會用 `git checkout` 然後再對該 commit 開一個 branch,改完後再 merge,而不是 `git reset`
- `-b` : 建分支並切換,只能建不存在的 branch
- 
- `git reset`
- 重新回到哪一個 commit (**可以往前 or 後**),<b>切換 HEAD + branch</b> 指向的 commit
- `git reset HEAD~1`
- 回到上 1 個 commit
- 可以改成 x 個
- para
1. `--mixed`
- 預設的
- 會把舊的 commit 的資料從 stage 移除,但不會真正從檔案移除(不會修改新 commit 的內容)
- 通常會用此來撤銷 commit
- 如果想要還原檔案狀態成該舊 commit
- `git restore {file}`
2. `--soft`
- 不會把 commit 的資料從 stage 移除,也不會真正從檔案移除
3. `--hard`
- 把 commit 的資料從 stage 移除,也從檔案移除
- 撤回 reset
- 不管是 mixed, soft, hard 都可以撤回 reset(也就是回到較新的 commit
- `git reflog` : 查看 HEAD 的移動紀錄,只要有換 branch, commit, reset 都會有紀錄,所以可藉由此看到較新的 commit 的 id,再 reset 回去就好
- ex.
- 原本
- 
- 想回到 test5 的 commit : `git reset HEAD~2` 後
- 
- 若想要撤回 commit,可以看 head reference log : `git reflog`
- 
- 可以看到原本 m2 commit 的 commid id
- 再 reset 回去就可以了 : `git reset ee417d3`
- 
- 特色
- 適用於還沒 push 到 remote 的時候
- 因為會更改 remote 的 commit 歷史
- ref
- https://gitbook.tw/chapters/using-git/reset-commit
- `git revert`
- 建一個新 commit 來取代取消該 commit
- ex.
- 原本
- 
- 想要回到 c1 commit 的狀態
- `git revert c1`
- 
- 和 `git reset` 不同,會建立一個新的 commit 以回到舊 commit 的狀態
- 特色
- 可以保留舊的 commit 紀錄
- 適用於已經 push 到 remote 的時候
- `git merge`
- 可合併切出去的 branch 回主要 branch
- 流程
- 初始 repo,僅有一個 main branch
- 
- 要新增新功能或改 bug,切 new branch : `git checkout -b bugFix`
- 
- 新增完功能,bugFix 分支 commit : `git commit -m "bugFix commit"`
- 
- 所以現在 bugFix branch 領先 main branch 一個 commit
- main 需要馬上做一些調整,也做 commit : `git switch main` + `git commit -m "main commit"`
- 
- 最後需要把新增的功能合併回 main branch : `git merge bugFix`
- 
- c4 是因為 merge 而自動產生的 commit
- 
- 補充
- 回到上一個 commit : `git reset HEAD~1`
- 
- Fast-Forward
- 若新的 commit 和原本的 branch 在同一條 commit history,就會直接更改新的 commit 改的地方(因不會有 conflict 的問題),<b>且不建立一個 merge commit</b>
- 好處:少一個 merge commit
- 壞處:無法保留合併的紀錄,不易觀察不同 branch
- 
- 
- fast forward : 預設
- 
- `--no-ff` : no fast forward
- 從 A branch merge B 和 從 B branch merge A 差在哪
- 一個是在 A branch 上多新增一筆 commit(合併 B branch 的),另個相反
- 但本地檔案內容會相同
- `git rebase`
- 可以調整 commit 的歷史紀錄
- 如果 commit 紀錄太醜,可以用此在送 pull request 前整理 commit,讓別人比較好 code review
- 可以用來把新功能的 branch 的 commit 接回原本 branch 的最新進度的 commit(和 `git merge` 有合併分支的功能)
- ex. 假設主要的 branch = main, 新功能切出去的 branch = x
- 切 branch : `git checkout -b x`
- 然後 main 和 x branch 都有新 commit(在切 x branch 之後的)
- 
- 現在在 x branch 做和 main rebase : `git rebase main`
- 
- 所以現在 x branch 的 commit 紀錄會是
- x 的 commit
- main 的 commit
- 不過這樣會讓 x branch 的 commit 紀錄有問題
- 因為後面(比較舊的)的 commit 歷史紀錄被改了,且一般只能新增新的 commit 在前面(比較新的),所以會 push 不上去
- 所以如果硬要 push 就得用 `git push -f`
- 所以最好不要在 main branch 上做 rebase
- ex.
- bugFix 在 c1 commit 從 main 切出去
- 
- `git rebase bugFix`
- 
- main branch 的歷史 commit 被改了
- 和 `git merge` 不同,不會有合併分支而產生的新的 commit
- 
- 好處
- 可以線性觀察 commit 歷史,且不會像 `git merge` 有多的 merge commit
- 用法
- 所以通常會先開一個新的 branch,當做完功能且 commit 好之後,在新的 branch 做 `git rebase main`
- bugFix 在 c1 commit 從 main 切出去,且兩個分支在切出去後都有新的 commit
- 
- 在非主要分支做:`git rebase main`
- 
- 注意:`C2`, `C2'` 和 `C3`, `C3'` 是不同 commit,原本的 commit 還會留存但變成沒有 branch 指向(不會馬上被刪掉,但過一陣子沒用會被 git 回收機制處理掉)
- 此時 bugFix 的 commit
- 最後再切回 main branch 做 merge
- `git switch main`
- `git merge bugFix`
- 也可用 `git rebase bugFix`,在這邊是一樣意思
- 或是 create pull request
- 
- conflict
- A 和 B 都修改到同個檔案的同個地方,無法讓 git 自動去 merge
- 流程
- 有 A 和 B,且有一專案有一檔案
```=
1234
4567
789
```
- A 先修改 `a.txt`
```=
1234
4567
78
```
- `git add .`
- `git commit -m "update by A"`
- `git push`
- 成功推上遠端
- B 再修改 `a.txt`
```=
1234
4567
7
```
- `git add .`
- `git commit -m "update by B"`
- `git push`
- 發生錯誤,因 commit history 和 origin 不同(遠端多了 A 的 commit,但本地沒有此 commit)
- 
- 所以要先 pull : `git pull`
- 
- 發生 conflict,且因為改到同一行,所以 git 無法 auto merge,所以會產生 conflict,就要手動解決
- 
- 看是要保留 local commit 的內容還是遠端的(兩個衝突的 commit 紀錄都會留存,只是要決定保留哪個 commit 的內容)
- 把 `<<<<` 那些刪掉,留要用的內容就好(`HEAD` 到 `=====` 中間是自己 local 的紀錄)
- 然後一樣新增修改紀錄
- `git add .`
- `git commit -m "merge A"`
- `git push`
- 最後 git log(上面是最新的)
- commit : merge A
- commit : update by B
- commit : update by A
- 如果 A 和 B 改到不同行,git 可以自動 merge commit
- `pull` 之前,本地少了 `Update README.md` 這個 commit,但沒有 `pull` 就新增了一條 `git commit -m "test3"` 然後直接 `push`,所以會 error
- 
- `pull` 之後
- 
- git 自動 merge,所以自動多了一條 merge 的 commit
- 最後再 `push` 到 remote 就 ok
- PR(pull request)
- 開發新功能時先切出去不同 branch,完成後送出 request 讓主 branch 去 merge 新 branch,也可以讓別人來做 code review
- 兩種情況
1. 開源專案
- 自己先 fork repo
- 修改好,新增 commit 並 push
- create pull request 讓原作者知道,他就會去審核是否可以 merge
3. 內部專案
- 開別的新功能的 branch
- 修改好,新增 commit 並 push
- 
- 這邊新開了 test5 branch,並多新增兩個 commit
- create pull request 讓其他 code reviewer 知道,他們就會去審核是否可以 merge
- 切到新的 branch, 案 contibute 的 open pull request
- 
- 選擇要 merge 的 branch
- 
- 但也有可能因為 conflict 不能 merge
- 
- 就要先切到新的 branch 再做 `git rebase {舊的要切回去的 branch}`
- 解決完 conflict 就可以 create pull request
- 
- 沒問題就案同意 merge
- 
- 新增的 commit 就會自動被 merge
- 
- `git diff`
- 看不同 commit 間差異
- ex.
- 指定兩個 commit
- 
- 看現在和上一個 commit 差異
- 
- 在 commit 前看看新增了哪些
- 
- 在 `git add .` 前後都可以看
- `git cherry-pick`
- 只想要 merge 指定的 commit
- 可能一個 branch 中有幾個 commit 正常,有幾個有問題
- ex.
- 有兩個 branch
- 
- main 只要 c2, c3 : `git cherry-pick c2 c3`
- 
- `git remote`
- `-v` : 列出遠端數據庫列表(包含 rul)
- 
- `add <遠端數據庫簡稱> <url>` : 加入遠端的來源,可以有多個
- 教學
- https://learngitbranching.js.org/?locale=zh_TW
- git tree
## Git Hook
### 介紹
- 在 git repo 中,在特定的 event (hook) 發生時,自動觸發特定的 script
### 架構
- 
- 讓 `.git/hooks` soft link 到一個共用的 hook directory
- 在 hook directory 放對應種類的 shell script
### hook 種類
- pre-commit
- 可以在使用者在 commit 時做一些檢查。
- 這些檢查包括自動格式化程式碼、自動測試等等。
- 
- commit-msg
- 公司或是團隊對於每個人提交的 commit 訊息有特定的要求,比如說字數、大小寫開頭等等
- 
- 
- pre-push
- 在 push 前進行某些測試,如果測試通過就推送到遠端私服器,否則就取消執行。
- 
### ref
- https://yhtechnote.com/git-hooks/
## Github Actions
- https://hackmd.io/vQR0RZlDTjOxcU9p8F6AYQ
## merge commits from 2 repos
1. 在專案 A 中添加專案 B 為遠端倉庫:
- `cd /path/to/project-a`
- `git remote add project-b /path/to/project-b`
2. 抓取專案 B 的所有資料:
- `git fetch project-b`
3. 將專案 B 合併到專案 A 中: 這裡假設你要合併專案 B 的 main 分支到專案 A 的 main 分支。
- `git merge project-b/main --allow-unrelated-histories`
- `--allow-unrelated-histories 允許合併兩個不同歷史的專案。`
## Good Commit Msg
### 組成
- 
- type
- 
### 範例
- 
- 
- 
- 
- 
- 
- 
- 
- 
- https://wadehuanglearning.blogspot.com/2019/05/commit-commit-commit-why-what-commit.html
## Conventional Release Bot
- Conventional Release Bot 是 Hahow 開源的 GitHub 機器人,它能夠根據 Conventional Commits 的規範,自動幫你產生 GitHub Releases 和 Git tags。
- 總結一下 Conventional Release Bot 的優點:
1. 自動化產生 CHANGELOG(GitHub Releases)
2. 自動化更新 SemVer 版本號(以 Conventional Commits 的 types 為基礎)
3. 通過友善的結構化 commit 規範,讓開發者更容易瀏覽更新歷史,提高對專案做出貢獻的意願
4. 更好地向人類(同事、使用者或其他利益相關者)傳達軟體更新的本質
- https://tech.hahow.in/%E5%A6%82%E4%BD%95%E8%87%AA%E5%8B%95%E5%8C%96-github-releases-%E6%B5%81%E7%A8%8B-6e7e33b61169
## 如何跟上 fork 的 repo 的 commit
- `git remote add upstream (upstream url)` : 添加 upstream 的 remote origin
- 
- `git fetch upstream`
- `git merge upstream/master` : 將 upstream merge 到我們當前分支。
## merge pr
1. Create a Merge Commit
- main 分支會增加一個 merge commit,且保留完整的分支 commit 歷史。
- 
2. Squash and Merge
- 不會在 main 中生成合併提交,只會有一個合併後的單一 commit
- 
3. Rebase and Merge
- 不會生成 merge commit,但會保留原分支中的每個 commit
## git submodule
- Git 可以做到 repository 中嵌入其他 git repositories, 相當於版本控制原本的 repository 之外,也把內嵌的 repositories 也納入版本控制的範圍,這功能被稱為 submodule 。
- Submodule 適合應用在多個 repository 共享 library, utility functions 的情境,可以節省各個 repository 重複開發的成本,例如下圖, repo A 與 repo B 共用同一個 submodule, 所以 repo A 與 repo B 都只要共同維護一份 submodule 即可
- 
## 清理重要敏感資料
- bfg
- 
- 速度更快
- filter-branch
- 
## work tree
- 
## Github Pages
- 免費建立個人、其他專案的靜態網站
- 免費 domain : username.github.io
### 教學
- ref : https://medium.com/%E9%80%B2%E6%93%8A%E7%9A%84-git-git-git/%E5%BE%9E%E9%9B%B6%E9%96%8B%E5%A7%8B-%E7%94%A8github-pages-%E4%B8%8A%E5%82%B3%E9%9D%9C%E6%85%8B%E7%B6%B2%E7%AB%99-fa2ae83e6276
---
## 簡易版
### 使用終端機
1. cd 到要更新的目錄
2. `git add .` : 把要更新的東西放到紀錄檔
> (將更改的檔案列入準備更新區 (staged))
4. `git commit -m '做了哪些更動'` : 提交紀錄(這次做的更動)
> 將更改的內容寫入本機資料
5. `git push origin master(branch name)` : 從本地push資料到雲端
> (將更改的內容寫入遠端資料)

---
### 使用 vscode
[教學網站](https://pythonviz.com/git/use-git-in-vs-code-basic-operations/)
#### 1. 加入新的修改(commit)
> 把需要加入修改(commit)的檔案加入「Staged Changes」
* 把檔案加入 **暫存變更 (Staged Changes)**

1. 首先在 Changes 的框框下,選擇 main.py 並點擊暫存變更(Stage Changes)的按鈕。
1. 完成後,會出現 Changes 框框了,多出了「Staged Changes」一欄,而 main.py 將會在 Staged Changes 以下。
1. 而且在File History 的框框裡,我們從本來的「Uncommitted changes」變成了「Staged Changes」。這是代表已經把 main.py 裡的更改提升至「Staged」的環節。
1. 留意我們的檔案現在是綠色的「Added」狀態,代表我們已經將新的檔案加入了 Staged Changes 和 Git 的視線範圍。
#### 2.把 Staged Changes 加入修改(commit)和分支(branch)
> 輸入修改信息(commit message)並在分支(branch)加入修改(commit)
* 在右上方「Message (Command Enter to commit on ‘master’)」的框框裡,我們應該**輸入一些有關這個修改(commit)有用的訊息**。例如我們加入了「main.py」,可以填寫「Create new file」。
* 
點擊「Command + Enter」,便成功把我們的 Staged Changes 變成一個修改(commit),加入了 master 這個分支(branch)了
完成後,我們可以見到以下的改變:
* Changes/Staged Changes 的框框現在是空白的,代表我們已經把所有檔案加入分支(branch)的修改(commit)
* Commits 的框框從「No commits could be found」多出了「Create new file」的修改(commit)。這是顯示我們現在使用的分支(即 master 分支)有了 1 個新的修改,就是我們剛剛加入的修改。如果我們放大(expand)這個項目,會見到 main.py 的更改
* File History 的框框多出了「Create new file」一行。由於 File History 會顯示我們現在開啟的檔案(即 main.py)以往有什麼修改,所以它告訴我們,在「Create new file」的修改了我們曾經更改了 main.py
* Branches 的框框裡,master 分支多出了一個「Create new file」的修改(commit),跟 Commits 框框的資訊一樣。
#### 3.更改已有的檔案及提交修改
修改現有的檔案(existing file),會發現檔案現在是處於黃色「Modified」的狀態。這是由於我們在 Git 的上一個修改(commit)已經加入了 main.py,所以 Git 知道這個檔案的存在。
> 紅色的部分代表我們上一個版本的內容
> 黃色的部分有新增的內容,這代表我們現在對檔案做出了什麼更改
#### 4.為現有檔案的更改加入修改(Commit)
整個流程其實跟上面新加入 main.py 的時候的流程一樣:
1. 儲存已更改的檔案
1. 把需要加入修改(commit)的檔案加入「Staged Changes」
1. 輸入修改信息(commit message)並在分支(branch)加入修改(commit)
### 5.還原(rollback)檔案及移除修改(commit)
> 有時候為檔案加入了新的修改(commit),但發現還是原來的版本比較好
以下是還原檔案的步驟。這些步驟就像是*加入修改的反轉*:
1. 在分支(branch)選擇修改(commit),並進行修改還原(Undo Commit)
1. 把變更從「Staged Changes」駁回至「Changes」
1. 在「Changes」裡放棄變更(Discard changes)
* 在 Commits 的框框裡用滑鼠浮動在檔案的修改(commit)上, 會有個像是還原的 捨棄變更「Undo Commit」 按鈕。

點擊 修改還原(Undo Commit)後,變更回到了「Staged Changes」的階段。這時候,其實就跟我們先前「Stage Changes」後,還未輸入修改訊息(Commit message)一樣。
現在我們的 main.py 已經變回黃色的「Modified」狀態。
我們把滑鼠浮動在「Staged Changes」的 main.py 上,會發現一個像減號的按鈕,讓我們可以「Unstage Changes」,即把這些變更駁回到「Unstaged Changes」的列表裡。

點擊「Unstage changes」以後,main.py 的變更來到了「Changes」的列表。
如果我們把滑鼠浮動在「Changes」的 main.py 上, 會發現又一個還原的標誌。這次,它的描述是「Discard Changes」,即是把這些變更放棄的意思。

點擊「Discard Changes」以後,您會見到一個彈出視窗,詢問您是否真的要放棄這些變更。這是 VS Code 給我們的最後警告,過了這次以後,我們便再不能恢復這些變更。
點擊藍色的「Discard Changes」按鈕繼續:
回到起初第 1 次修訂的版本
---
##### 專案啟用 Git
1. VS Code 的左邊,點擊「Git」的圖案,並點擊「Initialize Repository」
2. 完成後,原始檔控制(Source Control)版面應該有以下的選項:

3. 新檔案變成了綠色,而在 Explorer 的右側出現了「U」的字眼。「U」的全寫是 Untracked,意思就是這一個檔案未在任何的 Git 分支(branch)裡有紀錄。
4. 跳到「Source Control」的版面。留意在「Changes」框框裡多了「main.py」。這個「Changes」的框框十分重要,因為它會告訴我們有哪些檔案被修改了,包括新建的檔案。也能看到「File History」框框裡多出了一行「Uncommitted changes」。這個框框有助我們了解這個檔案的改變過程。由於我們的「main.py」檔案是新建的,所以在 File History 裡只有未在任何 Git 分支的紀錄。

---