記一次git的版本回退
背景
本地有個專案已經修改了很久(是自己的小專案不是公司的),檔案挺多的,還有大量的log檔案。一些資原始檔是中文名,工作區修改後使用了命令 git add .
本來在.gitignore檔案中設定一下就好了,但是實踐隔了有點久,忘了這事,就手賤都將工作區修改過的檔案提交到暫存區了……然後也就忽略了上傳檔案大小限制的事情就commit然後push了!
首先我們能看到這樣的報錯!這時候檢視github上的專案沒有推送成功的,還好!也就是說現在要解救的就是本地的版本庫了。
- 翻譯這些錯誤:前面是自己的檔案大小,後面說的是這檔案已經超過了github檔案大小限制100MB
那我瞭解到github是1G的空間,單個檔案限制100MB,超過50MB的檔案會警告!
- 這時我們要是希望能夠提前預防,第一,那麼用好.gitignore檔案,省心,大檔案直接過濾掉。第二,add的時候不要放入大檔案,也不要輕易add all,要選擇性的即使將工作區的檔案提交到暫存區,不追蹤大檔案!
好了,我們再回歸怎麼才能解決已經出現的問題!
解決思路
撤回版本庫中的版本:git revert和git reset
兩者的區別:前者revert是用一次新的commit來回滾之前的commit,單純從‘回滾’這一操作上看,根本沒太大區別,但是在以後如果進行merge的時候,版本記錄會出現區別,revert相當於用一次你想的commit來中和之前的提交,因此在日後合併的時候,這部分改變不會再次出現,但是reset是相當於把某個commit在branch上刪除掉,所以在branch再次merge的時候這些會館的commit還是會被引入。
而且,git reset是將HEAD的指標向後移動了下,而git revert還是會讓HEAD指標前進指標會指向新生成的commit版本。
先說一個遠端已經push成功的例子!
如圖:
此時,HEAD指標已經在提交D上了,A和B是正常提交,如果此時我們使用git reset --hard 2esdfc(B編號的前六位,我隨便編的)那我們的C和D兩次提交就不復存在了
但是遠端的HEAD指標依然不變,這樣要是push的話只能git push -f這樣不是很好,所以更推薦用revert。
git revert D git revert C
這兩個命令執行成功後,會生成兩個新的提交D和C,我們這裡稱為d,c比較好區分。而且,原來錯誤的提交記錄還在,如果有爭議的時候還可以找出提交記錄。並且這時就可以直接git push了。
從開頭對reset的命令解釋,大概就是如果中間出現錯誤提交,此時用reset,那麼之後大家的提交版本都會消失,那麼還是推薦revert,生成新的提交記錄,使HEAD指標繼續向前走。
回到我們的問題,我的問題並沒涉及遠端倉庫,只是本地的commit記錄,大致問題如下:
我的目標是將HEAD指標回退到B提交,這種情況也是最簡單的問題,這也是我一個人的專案,不涉及遠端和其他人分支merge的問題,所以直接reset解決即可,C的版本可以丟棄,將版本庫中的檔案退會到工作目錄中去,其實就是想保留檔案的改動,並且從暫存區中剔除跟蹤。
- 這就得先了解reset的三種模式了:--hard ,--mixed,--soft
使用這個命令前需要保證work tree是乾淨的。用圖說明一下各個命令後的效果。
- --soft:保留工作目錄,並把重置HEAD所帶來的差異放入暫存區(index)
- --hard: 直接重置index和work tree,也就是說所有的更改均被丟棄,也就是說你白乾了,上次coomit後的內容全都白乾!
- --mixed:只要reset後不加任何模式引數,其實就是mix模式,清空index暫存區,但保留工作目錄work tree,換句話說就是將所有差異都丟進工作區。正是我們想要的效果!
注意22:30那個提交記錄,2e17e5
這是改動記錄,太多
使用了--soft HEAD^ 就是回退上一個版本的意思,偷懶了,不想寫那六位數編碼。因為想看看soft的效果,所以這裡使用的是soft。
這時我們再用一次git reset就好了,保留work tree即可。
至此我們還是乖乖地去ignore檔案中新增不想被跟蹤的檔案吧,免得下次又提交不上去。
至於gitignore檔案的設定規則:大致想‘#’設定註釋,剩下的規則和linux檔案匹配差不多。
例如:/log/* 是忽略log資料夾下的所有目錄和檔案的意思
#匹配規則和linux檔案匹配一樣
#以斜槓“/”開頭表示目錄;
#以星號“*”通配多個字元;
#以問號“?”通配單個字元
#以方括號“[]”包含單個字元的匹配列表;
#以歎號“!”表示不忽略(跟蹤)匹配到的檔案或目錄
司甜甜愛吃蛋糕~~~