Git代碼回滾


部分內容翻譯自:Resetting,Checking Out & Reverting

Introduction

在git中以下三個命令可以幫助代碼回滾。

  • git reset
  • git checkout
  • git revert

checkout和reset通常是進行local或者private的撤銷。當push的時候會很容易發生沖突。

revert是一個對public撤銷安全的操作。因為會創建一個新的commit。

Prerequirements

可以看做three trees。

The three trees of Git

不同的操作對工作目錄、暫存區和commit history的影響。(index為暫存區)

img

Checkout

checkout可以把當前的HEAD指向某個具體的commit。

是commit級別或者文件級別的操作。文件級別會把文件內容變成要求的commit的內容。

git checkout是commit histroy樹的更新。

Example

HEAD和Main當前都指向d

![Move the HEAD ref pointer to a specified commit](/Volumes/D/zhangjunyu/筆記/Git/git代碼回滾.assets/01 git-sequence-transparent kopiera.png)

git checkout b

Sequence of commits on the master branch

Revert

會用一個新的commit來撤銷指定的commit上的更改。

是commit級別的操作。不能用在文件級別。

Reset

reset會重置three trees到要求的commit。

git reset --hard commit_id

提交:

git push origin

回退到上一個版本:

git reset --hard HEAD^ 

Sum

總結三個命令的常用場景。

Command Scope Common use cases
git reset Commit-level Discard commits in a private branch or throw away uncommited changes
git reset File-level Unstage a file
git checkout Commit-level Switch between branches or inspect old snapshots
git checkout File-level Discard changes in the working directory
git revert Commit-level Undo commits in a public branch
git revert File-level (N/A)

Commit-Level Operations

Git reset和git checkout的scope由傳給他們的參數決定。如果沒有指定file path,那么就是commit-level。

Reset A Specific Commit

把hotfix分支移動到兩個commit之前。

git checkout hotfix git reset HEAD~2

Resetting the hotfix branch to HEAD-2

reset通常用來撤回沒有和別人共享的commit。

除了撤回到之前的commit,也有可以用通過設置下列參數來更改暫存區或者工作目錄。

  • --soft:不會改變暫存區或者工作目錄。(即原本的更新內容還在工作目錄和暫存區,但是commit id回到之前的。可以重新git commit)
  • --mixed:暫存區會更新到指定的commit。但是工作目錄不受影響。默認參數。(可以重新編輯、然后add和commit)
  • --hard:暫存區和工作目錄都會更新到指定的commit。(即指定commit之后的更新會全部消失)

Checkout old commit

checkout通常可以用來切換分支,即HEAD會從一個分支切換到另一個分支:

git checkout hotfix

Moving HEAD from master to hotfix

因為可能會覆蓋本地的更改,所以git會強制我們commit或者stash所有的更改。

也可以用checkout來切換到之前的commit。例如:

git checkout HEAD~2

Moving  to an arbitrary commit

以為沒有任何的分支引用,所以這種情況的HEAD處於游離狀態。如果這個時候添加新的commit會非常危險,因為如果你切換到了其他的分支就沒有辦法再切回來了。所以HEAD處於游離狀態的時候,一定要新建一個分支來進行操作。

Undo Public Commits with Revert

revert會通過添加一個新的commit來撤銷一個commit。這是一個非常安全的撤銷操作。因為它不會更改原來的commit歷史。

git checkout hotfix git revert HEAD~2

Reverting the 2nd to last commit

這個操作會撤銷兩個commit之前的更新,但是是建立一個新的commit來實現的。

總的來說,git reset適合在private branch上使用,git revert適合在public上使用。

File-level Operations

Git Reset A Specific File

git reset會根據指定的commit id更新暫存區的內容。

git reset HEAD~2 foo.py

這個命令會按照兩個commit之前的內容來更新foo.py文件。

Moving a file from the commit history into the staged snapshot

--soft、--mixed和--hard在file level上不會有任何影響。

Git Checkout File

git checkout會更改工作目錄。不會更改HEAD的引用。

git checkout HEAD~2 foo.py

Moving a file from the commit history into the working directory

請注意,這會刪除對文件的所有后續更改,而 git revert 命令僅撤消由指定提交引入的更改。

Reference

  1. 拜托,不要再問我Git如何回滾代碼

  2. Resetting,Checking Out & Reverting

  3. Git中的git reset的三種參數的區別


免責聲明!

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



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