git命令——revert、reset


參考:如何在 Git 中重置、恢復,返回到以前的狀態

使用git時,如果對剛剛提交的后悔了怎么辦,如何撤銷?

方法一:手動修改

你把新增的文件刪了 或者 更改過的文件再改回來,然后再commit一次。這種方式不推薦,當修改量大的時候根本法沒法搞,雖然git diff可以幫助我們在最近兩次提交上做對比,但依然很難操作

方法二:使用reset命令

實際上,可以將reset其視為rollback(回滾”)- 將你的local environment指向以前的commit。 “本地環境”包括:local repository(本地存儲庫), staging area(暫存區域), and working directory(工作目錄)。

下圖是Git中的一系列提交記錄。 Git中的分支可以想象成一個指向特定提交命名的可移動指針。 在這種情況下,我們的主分支指向commit鏈中最新的提交。

查看提交歷史記錄

$ git log --oneline
b764644 File with three lines
7c709f0 File with two lines
9ef9173 File with one line
View Code

試想如果我們回滾到先前的提交會發生什么? 簡單 - 我們只需移動branch pointer(分支指針),Git提中reset命令就是為我們執行此操作的。 例如,如果我們想要將master重置為指向當前提交的兩個提交,我們可以使用以下任一方法:

$ git reset 9ef9173
View Code

或者

$ git reset current~2
View Code

下圖顯示此操作的結果。 在此之后,如果我們在當前分支(master)上執行git log命令,我們將只看到一個提交。

$ git log --oneline
9ef9173 File with one line
View Code

git reset命令還包括一些列參數,這些參數允許你使用最終提交的內容更新本地環境的其他部分。 這些選項包括:

hard:重置repository中branch pointer的指向,使用commit的內容填充working directory ,以及重置staging area(暫存區域)。

soft:僅重置repository中branch pointer的指向。

mixed:(默認值)重置repository中branch pointer的指向。重置staging area(暫存區域)。

使用這些選項在目標環境中非常有用,例如git reset --hard <commit sha1 | reference>。 這會覆蓋您尚未提交的任何本地更改。 實際上,它會重置(清除)staging area,並使用使用commit的內容填充working directory 。 在使用hard選項之前,請確保這是您真正想要做的事情,因為該命令會覆蓋任何未提交的更改。

方法三:使用revert命令

git revert命令的凈效果類似於reset,但其方法不同。 通常,reset的做法是移動分支指針到commit鏈其他位置,進而實現撤銷更改。revert命令會在鏈的末尾添加新的提交以“取消”更改。 見下圖,返回到只有兩行的版本的一種方法是reset當前提交,即git reset HEAD~1。另一種轉到兩行版本的方法是添加一個刪除三行版本的新提交 - 效果上等價於取消三行那個版本。 這可以使用git revert命令完成,例如:

$ git revert HEAD
View Code

由於這會添加一個新的提交,Git會提示commit消息:

Revert "File with three lines"
This reverts commit b764644bad524b804577684bf74e7bca3117f554.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#       modified:   file1.txt
#
View Code

下圖為revert操作后的commit鏈情況

如果我們執行git log,會看到之前的提交記錄

$ git log --oneline
11b7712 Revert "File with three lines"
b764644 File with three lines
7c709f0 File with two lines
9ef9173 File with one line
View Code

當前工作目錄內容是

$ cat <filename>
Line 1
Line 2
View Code

選擇revert還是reset?

如果您已經將commit鏈推送到遠端倉庫(其他人可能已經提取代碼並開始使用它),則revert是一種讓他人獲取更改的非常友好的方式。這是因為Git工作流很適合在分支結束時獲取額外的提交,這是因為 Git 工作流可以非常好地在分支的末端添加提交,但是當有人 reset 分支指針之后,會導致一些分支再也看不見(如果你記得住那些分支的sha1,是可以在reset回來的。但是怎么可能有人記得住那么多sha1)。

使用Git時的一個基本規則:在本地存儲庫中進行這些類型的更改,reset、revert都沒關系。但是,如果提交已經被推送到遠程倉庫而其他人可能正在使用它們的話,則不要做影響commit歷史紀錄的更改。

簡而言之,如果你rollback,undo或rewrite其他人正在使用的commit鏈的歷史記錄,那么當他們嘗試根據他們提取的原始鏈合並更改時,他們將會很頭疼。 如果您必須對已經被推送並且正由其他人使用的代碼進行更改,請在進行更改之前考慮進行通知,讓他人有機會合並自己的更改。 然后他們可以在侵權操作后提取新的副本而無需合並。

你可能已經注意到,在我們完成reset后,原始提交鏈仍然存在。 我們移動分支指針並將代碼重置為先前的commit,但它沒有刪除任何提交。 這意味着,只要我們知道分支指針的sha1,我們還能指回來。

git reset <sha1 of commit>

在替換commit時,我們在Git中執行的大多數其他操作中都會發生類似的事情。 創建新提交,並將分支指針移動到新的commit。 但舊的commit仍然存在。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM