iT邦幫忙

2025 iThome 鐵人賽

DAY 30
2

Git指令在多人協作的專案開發中,扮演了版本控制的核心角色,其重要性不言而喻。照理說,應該在前面的篇幅中提及,但Git指令在開發各階段,一直都有在使用,好像也不能放在特定章節之後,而且一些基本的指令,估計詢問ChatGPT也都能得到解答,故就決定在最後面,針對一些實務上有遇到的問題,彙整需要執行的Git指令組合,主要供查找之用。

Git指令,其實就是將專案的更新,於本機端及遠端專案間傳遞交流。只要先簡單地思考,本機更新檔案如何傳送到遠端(push),以及遠端的檔案如何下載到本機專案(pull),並且處理可能的檔案衝突,即本機及遠端都有更新內容,但兩者更新的地方不同,而造成要選擇是否保留或刪除該內容的問題。這些就是Git指令的主要任務,其餘較進階的指令,等更熟悉Git指令後,可以再深入學習。

基本Git指令

第一次要取得專案內容時,需要將遠端Git專案複製到本機,此時可使用clone指令。

# 複製專案到本機
git clone https://github.com/user/project.git

而一個基本Git指令的循環,包括pullpush指令。將遠端的資料抓到本機,更改後,再傳送到遠端。

# 確認自己目前在哪個分支,以及有哪些本機分支
git branch

# 先拉遠端最新內容,確認是否落後版本或有衝突
git pull origin main

# 查看專案有哪些變更
git status

# 加入特定檔案至暫存區
git add index.html
# 也可以加入全部檔案至暫存區
git add .

# 填寫提交訊息
git commit -m "更新了首頁的內容"

# 發送檔案到遠端
git push origin main

.gitignore檔案介紹

本機有一些環境設定檔案,內容包含一些機敏資料,如帳號密碼、API網址等,這些資料不適合發送到遠端公開,因此在push之前,通常會先設定.gitignore檔案,將不想發送到遠端的檔案位置,撰寫到裡面,當push時,就會自動忽略裡面的檔案,避免機敏資訊外洩。

# .gitignore示例
#frontend
node_proxy/
node_proxy/node_modules/
client/test.http
client/js/env.js
client/js/test.js
client/node_modules/
client/yarn.lock
client/vue.config.js
client/src/common/config.js
client_backup/

刪除遠端檔案,不影響本機檔案

而當不小心將不應公開的檔案傳送到遠端時,可以參考以下指令,將遠端的檔案刪除,但不會更動到本機的檔案。

# 可先確認ignore規則是否生效於特定檔案
git check-ignore -v server/envs/dev.env

# 從暫存區移除(但本機檔案會保留)
git rm --cached server/envs/dev.env

# 提交記錄
git commit -m "刪除遠端檔案.env"

# 再次傳送到遠端
git push origin main --force

刪除遠端檔案,同時刪除本機檔案

若要連同本機的檔案一起刪除,就直接刪掉本機的檔案,再傳送一次專案到遠端。

# 刪除本機檔案
rm client/js/wrong_file.js

# 加入暫存區
git add .

# 提交紀錄
git commit -m "刪除錯誤檔案wrong_file.js"

# 傳送到遠端
git push origin main

二階段遠端資料抓取(fetch + merge)

pull指令會直接更新本機檔案,如果在從遠端拉資料前,想先檢查遠端的版本內容是否為自己想要的內容,可先以fetch指令檢查,以避免直接影響工作檔案,等檢查完成,再以merge指令合併。

# 從遠端抓最新版本資訊到本機,但不會更改到本機檔案
git fetch

# 檢查遠端與本機檔案的差異
git diff origin/dev_frontend

# 可決定單獨檔案更新
git checkout origin/dev_frontend -- client/src/views/Employee.vue
#或
git restore --source=origin/dev_frontend -- client/src/views/Employee.vue

# 檢查檔案後,決定要合併時,再進行合併
git merge origin/dev_frontend

版本比對及衝突處理

若想要比對本機檔案與暫存區的差異,或已經執行git add後,暫存區要與最後一次提交的檔案進行比較,可分別執行以下指令。

# 本機檔案 vs 暫存區
git diff

# 暫存區 vs 最後一次提交(已經git add)
git diff --staged

當遇到衝突時,比較細緻的做法是,先暫存本機檔案,然後再pull遠端檔案,若有衝突,可以再手動處理

# 暫存特定檔案,-u可將未追蹤的檔案,也一起暫存
git stash push client/src/views/Employee.vue
git stash push -u client/src/views/Employee.vue

# 拉遠端更新檔案,此時可能會有衝突
git pull

# 可先查看暫存內容的差異
git stash list
git stash show -p           # 只看最新一筆stash
git stash show -p stash@{0} # 指定看特定一筆stash

# 將暫存區檔案還原(即把stash的變更套回工作目錄)
git stash pop     # pop會刪除暫存區的stash,但若有衝突,也不會刪除
#或
git stash apply   # apply不會刪除暫存區的stash

# 若僅需要取回暫存區中單一檔案
git checkout stash@{0} -- client/src/views/Employee.vue
#或
git restore --source=stash@{0} -- client/src/views/Employee.vue

# 若有衝突
# 先處理衝突檔案,決定何者的內容要保留或刪除

# 處理完成,加到暫存區,並加註解,傳送檔案到遠端
git add client/src/views/Employee.vue
git commit -m "合併 Employee.vue 並解衝突"
git push

# 處理完成,將stash刪除
git stash drop stash@{0}

進階衝突處理,針對單獨commit

衝突解決,也可以針對單獨的commit進行處理,但可能因為修錯單獨的版本,導致日後追蹤修正不易,還是建議以merge針對整個分支一同處理,以下指令僅供參考。

# 切換到要修正的分支
git switch dev_backend

# 只會帶來指定commit的更動,不會帶其他commit
git cherry-pick <commit-hash>                     # <commit-hash>為commit ID,用git log找
git cherry-pick <hash1> <hash2> <hash3>           # 一次挑多筆
git cherry-pick <oldest-commit>^..<newest-commit> # 挑連續區間

# 若發生衝突
# 編輯檔案解衝突
git add <解完衝突的檔案>
git cherry-pick --continue # 繼續處理下一筆

# 內容已存在、套用後變空,會出現empty commit訊息
git cherry-pick --skip     # 跳過

# 解到一半,不想解衝突
git cherry-pick --abort    # 回到操作前狀態
git cherry-pick --quit     # 保留目前衝突狀態,之後可繼續處理 

# 驗證與回復
git log --oneline --decorate -n 10

git reset --hard HEAD^     # 撤掉剛剛那一筆
git revert <那筆hash>      # 若已經傳送到遠端,則產生反向提交

總算完成30篇文章的撰寫,這一系列的文章,主要是在課堂學習過程中,面對網頁從撰寫、部署到展示之中,所面臨的問題,以及我如何想辦法問出答案的過程的紀錄。對我而言,這是方便日後遇到類似狀況時,能回頭查找並複習解決方法的筆記;但如果這些紀錄也能對剛踏入網頁開發領域的初學者有所幫助,那我將感到非常開心與欣慰。


上一篇
Day 29: Nginx反向代理(reverse proxy) & Ngrok對外公開網址
系列文
從零打造網頁系統:非資訊人也能完成的全端專題實作30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言