https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E7%BD%AE%E6%8F%AD%E5%AF%86html
https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystifiedgit
https://git-scm.com/docs/git-reset分佈式
https://www.liaoxuefeng.com/wiki/896043488029600/897013573512192spa
在使用git的時候,咱們通常提倡是不容許回滾。對於問題的追蹤和項目的發展歷程而言歷史記錄都是有用的。而且爲了節省一點存儲空間而丟失寶貴的代碼信息是不值當的。可是咱們開發中,確定會遇到特殊狀況須要回退。好比確實操做錯了一步歷史提交,致使倉庫混亂污染或是內容丟失,咱們須要回退到乾淨的一次提交,從新操做。3d
在git等全部的版本管理軟件中,刪除操做,只是增長一次記錄,內容並不會被刪掉,咱們能夠大膽的操做,這也符合版本倉庫的邏輯。只有特殊狀況才須要真正的刪除,作這種操做的時候須要特別注意,由於一旦失誤,沒法挽回。htm
從歷史記錄中刪除 參考 https://www.cnblogs.com/studywithallofyou/p/11772684.html https://www.cnblogs.com/studywithallofyou/p/11772844.htmlblog
要想理解git reset,那麼就要搞清楚git倉庫管理流程:開發
咱們修改完內容後,這些記錄單單是保存在咱們本地目錄下,也就是工做目錄。若是丟了,就是丟了,沒法找回。與普通磁盤上的文件同樣,除非到回收站找回。工作流
這時,若是運行了add,那麼內容就被記錄到本地的暫存倉庫,也就是index。這時若是刪除文件,在暫存區的內容還存在,並無丟失。it
以下圖,咱們建立了一個文件4,這時文件4在本地。咱們add到暫存倉庫,而後刪掉文件4,咱們發現又多了一條記錄刪除記錄,原來的4還存在,咱們能夠commit。原來的文件4並無丟失。
運行commit以後,修改的內容就被保存到了倉庫,修改了HEAD(HEAD就是指向當前倉庫在哪個提交歷史,不特殊修改,都指向最新的一次提交)。這時運行git status發現目錄是乾淨的。git裏面須要提交倉庫,暫存倉庫和本地目錄內容都徹底一致,纔是乾淨的,任何一個不一致都會有不一樣的提示。
好比上面的圖,提交的倉庫中沒有文件4,暫存倉庫中增長了4,因此顯示綠色的提示內容,add了文件可是尚未commit。可是本次又刪除了文件,本地目錄中的內容與暫存倉庫也不同,因此提示紅色的內容,由於算是警告,沒有add的內容是會丟失的。
修改
add
commit
理解了上面的流程,就能夠理解git reset了。git reset就是分別逆向操做,也就是把HEAD(提交的倉庫)回退到一個指定歷史,把HEAD、index(暫存倉庫)都回退到指定歷史,把HEAD、index和本地目錄的內容都回退到一個指定歷史。
git reset --soft就是把HEAD回退到指定歷史。運行後結果以下
也就至關於咱們add了修改的文件,本地目錄和暫存倉庫都已經一致了,就等待commit。若是咱們commit,能夠再次填寫commit記錄,也就實現了git commit --amend的功能。
git reset --mixed就是把HEAD和index都回退到指定的歷史。這個也是運行git reset不加參數時的默認規則。運行結果以下
至關於咱們僅僅修改了文件,還沒作任何處理。
git reset --hard這個是把HEAD、index和本地目錄的內容都回退到指定的歷史記錄。作這一步操做的時候必定要當心,最好把全部的內容都提交,而且push到遠程或是拷貝一份。由於這個操做會重置本地的內容到一個指定歷史。
咱們先運行git log,看到有三個提交歷史
運行git reset --hard HEAD~
咱們發現倉庫是乾淨的,而且原來的3文件沒了,運行git log參看
提交的歷史記錄也沒有了。
此次是真的回退到了指定歷史,全部的記錄都不見了,咱們能夠開心的(真的嗎?)在原來一個乾淨的分支上繼續寫代碼了。
世上有沒有後悔藥我不知道,可是git做爲一個先進的分佈式管理器,卻有無限可能。若是你一不當心,腦殼發熱,運行了git reset --hard,可是發現不是你想要的,原來的記錄也沒了。怎麼辦?大腦瞬間充血,一片空白。不要慌,首先冷靜下來,而後運行git reflog,這個命令是告訴你你的每一次對倉庫操做的歷史記錄,以下
看一下最上面的幾條,第一條告訴你當前在e86d948這個提交記錄,經過reset切換過來的。對照上面的git log,能夠發現這個是第二個提交歷史,也就是咱們git reset --hard HEAD~的時候回退的分支。第二條記錄告訴咱們當前是fc9fbc6分支,經過reset回退到這個分支的,咱們能夠參考上面的git log記錄,這個就是咱們想要回去的分支。好了,有了記錄的哈希值,咱們只需再運行一次git reset --hard,以下
查看一下git log
回來了。
git不會刪除任何已經提交到版本庫的內容,除非你非要專門特殊這樣作,而且爲了再給你一次機會,像git reset這樣,就算你明確說明不要了,它也不會立馬刪除,除非超過必定時間或是你主動運行git gc等操做,把無用的,沒有關聯的內容刪掉。否則,那條記錄仍是在本地倉庫,只不過它沒有被載入歷史的長河中。