原來是 Git 是時光機
可惜不能傳送人 (欸) 之版控很重要
在工程師亦或是設計師的領域,版本控制是相當重要的技術,從前檔案備份都是 v1.0, v-2.0, …v-final-0, v-final-2...說是最終版也還是一直改,心裡 os: 再騙阿,說不會改還一直改,欺騙我感情 (誤),光看檔名也不知道內容到底改了什麼,檔案打開來比對也要找很久,為了讓世界更美好,懶惰是造就工程師發明更好工具的動力,好了~別催,我前言結束。
因為自己是金魚腦,學了一點新東西,三天沒碰可能就忘記,所以來筆記粗略的 Git 要怎麼使用。(會陸續補充,先掌握 5% 最基本也最重要的指令)
Git 中文版練習工具推薦:
https://learngitbranching.js.org/?locale=zh_TW
起手式
VSCode 可以用快捷鍵 ctrl + `
快速開啟 git 控制面板。
設定使用者 (user) 帳號和信箱
git config --global user.email "xxx@gmail.com"git config --global user.name "chloe"
檢查是否設定成功 — git config — list
常用的基本指令:
- 新增資料夾 — 假設新增一個 project-demo 的資料夾
mkdir project-demo
- 進入資料夾 —
cd project-demo
- Git 初始化 (安裝數據庫) —
git init
- 新增檔案 — 假設新增首頁 index.html 檔
touch index.html
- 加入索引值 —
git add .
點 (.) 指全部檔案都加入 (通常用點就好,比較快速,也可指定單一檔案加入 → 在 add 後方寫入檔名即可) - 查看狀態 —
git status
orgit st
- 新增 commit 紀錄 —
git commit -m '建立 index.html'
or 縮寫git ci -m '建立 index.html'
- 查詢 commit 紀錄 —
git log
- 在 Github 新增遠端數據庫,本地端連結到遠端 —
git remote add origin git@github.com:帳號名/遠端數據庫名.git
- 把本地端資料推送到遠端數據庫 —
git push -u origin master
分支 (branch)
建立分支 (git branch)
版本控制預設都會有個主線 master (Github 近期主線預設名改成 main,詳情可點此查看), 主線通常是最終上線版本,在新增修改編輯的時候,不會直接動到最終版本,一定會開分支去操作,確定都沒問題再合併到主線上,所以分支概念很重要。
- 新增分支 — 假設新增一個 dev (develop,表示開發中) 的分支
git branch dev
- 切換分支— 切到分支 dev
git checkout dev
合併分支 (git merge)
在分支上完成 commit 之後,目前分支上的版本已經比主線版本還要新,確認分支沒問題後,我們要 (HEAD) 回到主線,合併分支,讓主線與分支同步都是最新版。
- 切換分支 —回主線
git checkout master
- 合併分支 —
git merge dev
合併分支 (快轉模式)
過程中,若 master 沒有任何更新,表示初始 commit 位置沒有變動,此時用 master 去 merge dev 就會觸發快轉模式。
合併分支 (非快轉模式)
可以特別強制不要快轉模式,這樣 master 即使沒更新,合併 dev 時也會有 commit 紀錄。git merge 分支名稱 — no-ff
取消快轉,用意是希望知道在哪個時機點 merge 了
本地分支衝突
並非每次分支合併都會一帆風順,如果剛好不同協作者合併內容同時修改到同一行 CODE 時,就會導致衝突。
解法:彼此要溝通,看最終要用哪個版本 XD
分解衝突流程
git merge dev
- 發生衝突,用
git status
查看狀態,衝突的地方狀態會是Unmerged
- 修改確認衝突的地方,重新加入索引
git add <原衝突的檔名>
- 再一次
git commit
完成合併
遠端協作分支衝突
本地端 push 到遠端時,如果有衝突,git 會要求你先把遠端的資料 pull 下來,然後解決衝突後再 git add .
和 git commit
,再次 push 回遠端,會產生新的兩個 commit 紀錄,衝突的 commit 和解決衝突後合併的 commit。
指令回顧:
- 建立分支:
git branch <分支名稱>
- 切換分支:
git checkout <分支名稱>
- 合併分支:
git merge <分支名稱>
- 合併分支(取消快轉):
git merge 分支名稱 — no-ff
還原版本 (git reset)
總是會有 commit 之後又反悔,覺得之前版本寫得比較好的狀況,這時候還原就很重要了,Git 就好比時光機器,能讓你來回穿梭。
情境:假設現在有三個 commit 紀錄,我要回到第一個 commit
- 還原到第一個 commit,檔案想保留:
git reset HEAD^^
- 還原到第一個 commit,檔案不想保留:
git reset HEAD^^ --hard
--hard
是 reset 的其中一個參數,表示在還原過程中,commit 裡面的檔案都要捨棄時,就可使用。
HEAD
也就是目前指標位置,^
就是向前一個版本,,兩個 ^^
就是向前推兩個版本,除此之外,用 ~
也可以。如 git reset HEAD~~
,如果向前推進的版本很多,也可以用數字取代,如git reset HEAD^2
。
所以 git reset HEAD^2
等於 git reset HEAD~~
。
還原大絕招 (git reflog)
假使我們用了 git reset
語法,將版本還原到前面的版本,用 git log
上看也看不到那些紀錄。但此時你又想把 commit 救回來該怎麼辦?
在 git 裡的有些指令會讓你以為檔案不見 (被刪除) 了,但其實只是隱藏到你肉眼看不到的地方,用 git reflog
指令可以把所有看似被刪掉的 commit 都顯示出來,只要找的到 commit 上面的 SHA-1 值 (表 commit 上一長串英文與數字的代碼組合),就可以把 commit 給救回來。
補充觀念:
- 遠端下載到本地端
pull
- 本地端到遠端
push
- 遠端到遠端
PR (pull request)
git clone
跟git pull
的差別在那邊?
clone
是複製一份下來,用於本地沒有專案時。pull
是從遠端數據庫更新資料下來,是專案已經成立的狀態。
參考資料來源:
- 六角學院 - Git & GitHub 教學手冊
- 高見龍 @ 五倍紅寶石 — 為你自己學 Git