【工具】一份值得收藏的 Git 異常處理清單
本文首發(fā)于政采云前端團(tuán)隊(duì)博客:一份值得收藏的 Git 異常處理清單
https://www.zoo.team/article/git-exception

前言
本地工作區(qū)文件恢復(fù)
遠(yuǎn)程分支刪除后,刪除本地分支與其關(guān)聯(lián)
修改提交時(shí)的備注內(nèi)容
修改分支名,實(shí)現(xiàn)無縫銜接
撤回提交
撤銷本地分支合并
恢復(fù)誤刪的本地分支
不確定哪個(gè)分支有自己提交的 commit
(一)本地工作區(qū)文件恢復(fù)
語法:git checkout <filename/dirname>
命令:git checkout 1.js
這一命令主要用于本地工作區(qū)文件的撤回,下圖是一個(gè)工作區(qū)文件被刪除后的完美恢復(fù)過程。

(二)遠(yuǎn)程分支刪除后,刪除本地分支及關(guān)聯(lián)
git branch --set-upstream-to=origin/master master 建立本地分支與遠(yuǎn)程分支的關(guān)聯(lián),從 master 拉出的分支可以自動(dòng)建立與遠(yuǎn)程已有分支的關(guān)聯(lián),這樣可以很方便的使用 git pull 和 git push 拉取遠(yuǎn)程分支的代碼和將本地分支提交到遠(yuǎn)程。git push origin --delete feature/test 刪除掉對(duì)應(yīng)的遠(yuǎn)程分支之后,刪除本地分支關(guān)聯(lián)。
語法:git branch --unset-upstream <branchname>
命令:git branch --unset-upstream feature/test
刪除掉關(guān)聯(lián)關(guān)系之后,用 git branch -vv 命令可查看到本地分支與遠(yuǎn)程分支的關(guān)聯(lián)關(guān)系如下圖所示,可觀察到 feature/test 分支已經(jīng)沒有關(guān)聯(lián)的遠(yuǎn)程分支了。

(三)修改提交時(shí)的備注內(nèi)容

語法:git commit --amend
git commit --amend
使用 git log --pretty=oneline 查看內(nèi)容,發(fā)現(xiàn)已經(jīng)成功修改啦。需要注意的是此項(xiàng)命令會(huì)修改提交時(shí)的commit-id,即會(huì)覆蓋原本的提交,需要謹(jǐn)慎操作。
(四)修改分支名,實(shí)現(xiàn)無縫銜接
語法:git branch -m <oldbranch> <newbranch>
git branch -m feature/stor-13711 feature/story-13711
執(zhí)行完之后發(fā)現(xiàn)文件的工作區(qū)已修改內(nèi)容一點(diǎn)都沒有變化,真正的實(shí)現(xiàn)了無痛過渡,皆大歡喜!
(五)撤回提交
已將更改交到本地存儲(chǔ),需要撤回提交
用新的提交內(nèi)容替換上一次的提交
本地提交了錯(cuò)誤的文件
已將更改提交到本地,需要撤回提交
語法:git reset --soft [<commit-id>/HEAD~n>]
命令:git reset --soft HEAD~1
命令執(zhí)行完成后,查看文件變更記錄,可發(fā)現(xiàn)如下圖所示:

文件變更記錄與未提交之前的文件變更記錄是一致的,只是撤銷了 commit 的操作。
用新的更改替換撤回的更改
語法:git reset --mixed [<commit-id>/HEAD~n>]
命令:git reset --mixed HEAD~1
命令執(zhí)行完成后,查看文件變更記錄,可發(fā)現(xiàn)如下圖所示:

已變更的文件都未添加到暫存區(qū),撤銷了 commit 和 add 的操作。
本地提交了錯(cuò)誤的文件
語法:git reset --hard [<commit-id>/HEAD~n>]
命令:git reset --hard HEAD~1
命令執(zhí)行完成后,查看文件變更記錄,可發(fā)現(xiàn)如下圖所示:

已追蹤文件的變更內(nèi)容都消失了,撤銷了 commit 和 add 的操作,同時(shí)撤銷了本地已追蹤內(nèi)容的修改;未追蹤的內(nèi)容不會(huì)被改變。從上面的效果可以看到,文件的修改都會(huì)被撤銷。-hard 參數(shù)需要謹(jǐn)慎使用。
(六)撤銷本地分支合并
git reset 和 git revert。reset 的語法和命令之前已經(jīng)介紹過,不做贅述, revert 的語法和命令和 reset 一致。但是產(chǎn)生的實(shí)際效果會(huì)有不同。
語法:git revert <commit-id>
命令:git revert 700920
下圖為執(zhí)行命令后的效果:

從需要提交到遠(yuǎn)程分支的角度來講,reset 能夠“毀尸滅跡”,不讓別人發(fā)現(xiàn)我們?cè)?jīng)錯(cuò)誤的合并過分支(注:多人協(xié)作中,需要謹(jǐn)慎使用);revert 則會(huì)將合并分支和撤回記錄一并顯示在遠(yuǎn)程提交記錄上。
(七)恢復(fù)誤刪的本地分支
誤刪的分支為 feature/delete,使用 git reflog 命令可查看到該倉(cāng)庫(kù)下的所有歷史操作,如下圖所示:

語法:git checkout -b <branch-name> <commit-id>
命令:git checkout -b feature/delete HEAD@{2}
git reset --hard HEAD@{1} 即可實(shí)現(xiàn)硬性覆蓋本地工作區(qū)內(nèi)容的目的。git reflog 命令獲取到的內(nèi)容為本地倉(cāng)庫(kù)所有發(fā)生過的變更,可謂恢復(fù)利器,既可向前追溯,亦可向后調(diào)整,滿滿的時(shí)光追溯器的趕腳啊。。。(八)不確定哪個(gè)分支有自己提交的 commit


語法:git branch --contains <commit-id>
命令:git branch --contains 700920
命令執(zhí)行后可以看到包含該問題提交的分支如下圖所示,就可以很方便的在對(duì)應(yīng)分支上修復(fù)內(nèi)容啦。

總結(jié)
本文介紹的是實(shí)際工作場(chǎng)景中可能出現(xiàn)的幾種異常情況及解決方式,希望能夠?qū)Υ蠹矣兴鶐椭?,不足之處敬?qǐng)指正。實(shí)際上現(xiàn)在已經(jīng)有很多 Git 操作對(duì)應(yīng)的工具可以使用,需要明白的是工具中的每個(gè)操作等同于 Git 命令行的哪個(gè)命令,會(huì)有什么樣的結(jié)果,以避免一些不必要發(fā)生的錯(cuò)誤。
參考文獻(xiàn)
Git 錯(cuò)誤集錦和修復(fù)方法 (https://www.edureka.co/blog/common-git-mistakes/#pushed)
Git 中.gitignore的配置語法 (https://www.jianshu.com/p/ea6341224e89)
git reset 和 git revert (https://juejin.im/post/5b0e5adc6fb9a009d82e4f20)
歡迎關(guān)注「前端雜貨鋪」,一個(gè)有溫度且致力于前端分享的雜貨鋪
關(guān)注回復(fù)「加群」,可加入雜貨鋪一起交流學(xué)習(xí)成長(zhǎng)
