天天看點

git的使用——reset

git reset 指令用于回退版本,可以指定退回某一次送出的版本。

有三種指令方式

知識前提:git重要的三個工作區域:

  1. 工作區(Working Directory):寫代碼的目錄。就是項目代碼存放的目錄(git add 之前的目錄)。
  2. 暫存區(index/stage):工作區與版本庫之間的緩沖地帶。用 git add 把檔案添加進去,實際上就是把檔案修改添加到暫存區,檢視記錄 git status
  3. 倉庫區:git commit 送出到本地分支的,檢視記錄 git log

–mixed為預設的,可以不用帶該參數

  1. 用于重置暫存區的檔案,此時曆史記錄與上一次的送出(commit)保持一緻,工作區檔案内容保持不變(有上次修改的内容)。移動 HEAD 指針,改變暫存區内容,但不會改變工作區
  2. 原有檔案内容的變更 :修改内容還在,變成未add的狀态
  3. 目錄結構的變更(增加或者删除檔案):

    新增檔案: 還存在,變成未add的狀态(目錄結構中檔案變成紅色,需要執行指令git add . 再執行git commit )

    删除檔案:目錄結構中還是沒有,可以直接執行git commit

–soft用于回退到某個版本

  1. 僅僅移動目前 Head 指針,不會改變工作區和暫存區的内容
  2. 原有檔案内容的變更 :修改内容還在,變成已add的狀态(未commit)
  3. 目錄結構的變更(增加或者删除檔案):

    新增檔案:還存在,變成已add的狀态(目錄結構中檔案變成綠色,可以再次執行git commit );

    删除檔案:目錄結構中還是沒有,可以直接執行git commit

–hard 參數撤銷工作區中所有未送出的修改内容,

  1. 将暫存區與工作區都回到上一次版本,并删除之前的所有資訊送出,目前 HEAD 指針、工作區和暫存區内容全部改變
  2. 原有檔案内容的變更 :修改内容丢失(修改的代碼不會變成未add的狀态)
  3. 目錄結構的變更(增加或者删除檔案):新增檔案丢失、删除的檔案相當于沒删

使用場景

–mixed

1 使用完 reset --mixed 後,執行 git add 将這些改變過的檔案內容加入 暫存區(index)中,再執行 git commit 将 Index 暫存區中的內容送出至倉庫( Repository )中,這樣一樣可以達到合并 commit 節點的效果

2 也可以用于發現add錯誤了,可以執行git reset HEAD來重置暫存區(index)的檔案

–soft

1 使用完reset --soft後,commit_id之後送出的内容會被放入暫存區(index)中,此時已經add了,可以直接執行commit,将commit_id之後的送出作為一個commit來統一進行送出,減少不必要的log記錄

–hard

1 使用 git reset --hard HEAD(HEAD也可以是某個commit_id) 來強制恢複 git 管理的檔案夾的內容及狀态;此時目标節點(commit_id)後的所有送出都會被删除

git log // 查詢要復原的 commit_id
 // 這裡的commit_id是目前送出錯誤的想要撤回的commit之前的那個正确的commit
 // 執行前,先将本地代碼切換到對應分支
 git reset --hard commit_id // HEAD 就會指向這個commit_id的送出記錄
 git push origin HEAD --force // 強制推送到遠端
           

這種操作存在一個問題,伺服器上的代碼雖然被還原了,但假如有多個人在這個分支上開發,他們本地的版本依然是比伺服器上的版本高的,是以,别人再重新送出(push)代碼的話,你撤銷的操作又會被重新,你上面的操作也就白操作了。解決辦法是,讓别人把本地的分支先删掉,然後重新從伺服器上拉取分支,或者你在對方送出完所有本地代碼之後對方沒有再進行修改代碼,這個時候你送出了,發現你送出的有問題,再進行reset操作,然後讓對方拉取(pull)最新的代碼也ok,最主要的就是對方本地沒有你要reset的代碼即可

2 誤删恢複

如果復原代碼之後發現複制錯了 commit_id,或者誤删了某次 commit 記錄,也可以通過下方代碼恢複:

git relog // 複制要恢複操作的前面的 hash 值
git reset --hard hash // 将 hash 換成要恢複的曆史記錄的 hash 值