Git 各種修改提交歷史的情境和解法
本文以情境為主軸介紹,每個段落都是一個獨立的情境,遇到問題查這篇文章基本上都能解決,不用再去網路上找半天。
以下是預備知識
- 大部分都用互動式變基完成,操作方式請見使用互動式變基任意修改提交歷史。
hash^
的^
代表該 hash 的前一個提交,~n
代表前 n 個提交。--amend
可以加上--no-edit
表示不修改 commit 訊息。- rebase 時 git 會自動幫你 checkout,這時候查看
git status
會顯示「互動式重定基底動作正在進行中」,使用git branch
查看則會顯示目前分支為「無分支,重定 main 的基底」 (no branch, rebasing main)。 - 遇到合併衝突請看如何解決合併衝突,實際操作過才會清楚。
修改提交訊息
-
修改前一個提交:
git commit --amend
-
修改更早的提交:
git rebase -i hash^
- 把想修改 message 的 commit 前面的
pick
改成r
- 跳出 commit message 視窗,直接修改
- 附帶一提 Vim 編輯介面中的提交紀錄,上到下順序是從舊到新
修改前一個提交內容
完成一個 feature 之後很開心的 commit,伸個懶腰馬上發現有 typo 要怎麼修改呢?
- 修正 typo
git add .
git commit --amend
或者,放棄前一個 commit:git reset --soft HEAD^
話說這天天在發生...
修改更早的提交內容
發現舊 commit 有地方沒修好,要怎麼單獨修改那個 commit?
git rebase -i hash^
- 該 hash 前面改成 edit 或者縮寫 e
- 修改文件後加入追蹤
git add <file name>
,注意不需提交 - 完成 rebase
git rebase --continue
資訊
互動式變基過程中不需使用 git commit
,使用的話會變成插入一個新的提交紀錄。
合併提交
覺得提交太瑣碎了想要合併:
git rebase -i hash^
- 想要 被合併 的 commit
pick
改s
,他會合併到前一個 commit - 完成 rebase
git rebase --continue
插入提交
- 互動式變基指定提交
git rebase -i <hash>^
- 把該 hash 的
pick
改為edit
或e
,儲存並且退出 vim 編輯器 - 想怎麼改就怎麼改,甚至可以在這裡使用
git cherry-pick
- 修改結束後使用
git rebase --continue
需要注意的是 rebase 比較危險,如果還不熟悉建議先在原本位置建立一個備份分支。如果 rebase 過程中想放棄就使用 git rebase --abort
拆分提交
- 同插入提交的 1, 2
- 清除最新一個提交
git reset HEAD^
- 把檔案依序
git add
git commit
- 拆分結束後使用
git rebase --continue
修改提交的順序
完成多項功能開發,想要整理,例如把 fix 和 feat 開頭的分類排放:
git rebase -i hash^
- 直接調整提交順序並儲存
- 完成 rebase
git rebase --continue
刪除提交
git rebase -i hash^
- 把該 commit
pick
改成drop
或整行刪掉 - 完成 rebase
git rebase --continue
不影響當前分支,修改一個特定的提交
有兩種方式,分別對應小型和大型修改。
小型修改直接使用 git rebase -i
,改為 edit 模式即可。
大型修改使用 git checkout -b <new-branch-name> <hash>
在指定 commit 建立新分支,直接修改後看你要怎麼處理這個修正。
結語
每個情境了不起就五句話,某賣課網站可以把每個情境都寫成一篇文章還被 Google SEO 排到很前面,佩服佩服= =