以下接續昨天,更多git的指令教學
移動分支指標 & 處理暫存/工作區
git reset
的本質是 把目前分支的 HEAD(指向某個 commit 的指標)移到另一個 commit,同時可決定要不要改變暫存區或工作目錄。
模式 | 指令範例 | 會發生什麼事(簡單) |
---|---|---|
--soft |
git reset --soft <commit> |
只移動 HEAD(把 commit 撤回),保留暫存區與工作目錄不動 |
--mixed (預設) |
git reset <commit> 或 git reset --mixed <commit> |
移動 HEAD,把暫存區還原到該 commit |
--hard |
git reset --hard <commit> |
移動 HEAD,重置暫存區與工作目錄到該 commit |
(想改 commit 訊息或再加入檔案)
git reset --soft HEAD~1
HEAD~1
= 前一個 commitgit commit --amend
或重新編輯 commit message。(但不在暫存區)
git reset HEAD~1
# 等同 git reset --mixed HEAD~1
git status
裡的「修改但未 staged」。(會丟掉本地未提交的改動)
git reset --hard a1b2c3d4
a1b2c3d4
是 commit hashorigin/main
的狀態(把本地改動捨棄,讓本地與遠端一致)
git fetch origin
git reset --hard origin/main
git add
的檔案(unstage)git reset HEAD file.txt
file.txt
從暫存區拿掉,變成修改但未 staged ( 已修改但未加入暫存區 )。安全在公開歷史上撤銷
git revert <commit>
會在歷史上新增一個「反向 commit」,它的效果是取消指定 commit 的改動,但保持歷史完整(不改寫已存在的 commit)。
適合已經 push 到遠端、需要撤銷但不能改寫歷史的情況。
範例:
git revert a1b2c3d4
# 會互動要求輸入 revert 的 commit message,或用 -m 指定
a1b2c3d4
的變動互相相反 ( 回到原本狀態 )。救火工具:找回走掉的 HEAD
git reflog
記錄了你本地 HEAD 的每一次移動(例如 commit、reset、checkout 都會留下紀錄)。git reset --hard
、誤刪分支、或執行 commit --amend
後找回「關鍵 commit」的第一條路徑。reflog 是本地的(不會上傳到遠端),會在本地保留一段時間(預設多久取決於 Git 設定,通常 90 天)。步驟:
git reflog
輸出可能像:
a1b2c3d (HEAD@{0}): reset: moving to HEAD~2
c3d4e5f (HEAD@{1}): commit: 新增功能 X
d4e5f6a (HEAD@{2}): commit: 修 bug Y
...
c3d4e5f
),然後建立新分支或把分支指回去:git checkout -b recovery c3d4e5f
# 或把 main 指回去
git reset --hard c3d4e5f
reset --hard
,可以先 git checkout -b recover <hash>
,確認內容沒問題再決定下一步。(取代某些 checkout
用法,較新)
git restore file.txt
git restore --staged file.txt
這兩個功能在舊版 Git 常用 git checkout -- file.txt 與 git reset HEAD file.txt,新寫法更直觀。
(把單一 commit 套到另一分支)
git cherry-pick a1b2c3d
互動式改寫歷史
git rebase -i HEAD~3
pick
、squash
、reword
等操作來合併或修改 commit。(二分法找出壞 commit)
git bisect start
git bisect bad # 當前版本有 bug
git bisect good v1.2 # 指定一個已知沒有 bug 的 commit/tag
# Git 會自動 checkout 到中間 commit,跑測試然後 git bisect good/bad
# 最終會告訴你引起 bug 的 commit
git bisect reset
(臨時放下未完成工作)
git stash push -m "WIP: new feature"
# 查看 stash
git stash list
# 恢復(套用)
git stash pop
# 從 stash 建分支
git stash branch fix-branch stash@{0}
(刪除未追蹤檔)
git clean -nd
git clean -fd