git reset rebase revert 版本回退


http://rubyist.marsz.tw/blog/2012-01-17/git-reset-and-revert-to-rollback-commit/

http://blog.csdn.net/troy__/article/details/39968453

https://my.oschina.net/MinGKai/blog/144932

 

 反轉提交 revert

  反轉已經提交的變動,最簡單的方式是使用git revert命令。此命令通過在版本庫中 創建一個"反向的"新提交來抵消原來提交的改動
  通常Git會立即提交反轉結果,但是也可以通過 -n參數告訴Git先不要提交,這對於需要反轉多個提交非常有用。運行多個 git revert -n命令,Git會暫存所有的變更;然后做一次性提價。
在反轉操作的時候必須要提供提交名稱,以便讓Git知道要反轉什么。舉個例子,想要反轉提交9267f21和HEAD。提示,反轉總是按照從新到舊的倒序來操作,即最后的提交最先反轉。這樣可以避免在反轉多個提交的時候,遇到一些不必要的沖突。

 

 
 
 
復位  reset (用來修改HEAD指針)
默認是--mixed
 
     Git提供了復位版本庫到一個特定版本的功能,命令git reset是以提交名稱作為參數的,默認值是HEAD。
     可以用"^"和“~"作為提交名稱的修飾符來指定某個版本。HEAD^是指要復位一個提交,9267f21~3是指要復位540ecb7之前的三個提交。
     命令git reset可以在復位版本庫后,暫存工作目錄樹中因復位產生的與版本庫的差異,以便提交。這 對於在之前的提交中發現錯誤並需要更改時非常有用。
     這是通過--soft參數實現的,它使得Git暫存所有的因復位帶來的差異,但不提交它。之后,用戶可以修改這些內容再提交,或者干脆扔掉這些東西。
     另一個選項是--hard,這個選項會從版本庫和工作目錄樹中同時刪除提價。--hard就好像版本庫中的刪除鍵,並且不可以修復。
     下面簡單演示這個選項的用法。前面示例中最后一次提交反轉了兩個文件的修改,假設這並無必要,下面撤銷這個提交:
$ git reset -- hard HEAD^

重新改寫歷史記錄(rebase)

     有時我們需要改寫歷史記錄,主要有以下幾種用法:
  • 給歷史記錄重新排序
  • 將多個提交壓合成一個提交
  • 將一個大的提交分解成為多個提交
     這其實是使用分布式版本控制系統帶來的好處,如果是集中式,那么做這些操作會對其他程序員造成巨大的困惑。
     Git的交互式rebase命令,即 git rebase -i,能夠完成這類改寫歷史的工作。用這個命令,可以重新塑造歷史。
=-===============================================================

個人比較推薦用 reset 或 rebase -i, 底下將會同時介紹 revert 和 reset 的方法

commit 如下

1
A -> B -> C -> D -> E

想要還原到 commit C 之後的狀態 (也就是把 D 和 E rollback)

用 git revert
1
2 
git revert E git revert D

結果:

1
A -> B -> C -> D -> E -> F -> G

F 是還原 commit E 修改結果的 commit
G 是還原 commit D 修改結果的 commit
因此 revert 只會讓 commit 繼續往前
優點是可以針對某個 commit 進行還原 並且留下還原記錄

用 rebase -i  //把commit id往前多指幾個

有關 rebase -i 的詳細使用方式可以參考這篇

假如想要抽掉某個 commit 又不想留下記錄, rebase -i 就很好用了

假如只想要還原 D 變成 A -> B -> C -> E

1
git rebase -i C

這時候會出現文字編輯

1
2 
pick D xxx pick E ooo

把 pick D xxx 整列移除後儲存就可以了 若中間有遇到衝突則必須自行修正後再

1
2 
git add . git rebase --continue
用 reset

用於做整段 commits 的還原
例如希望還原到 B commit 以後的狀態變成

1
A -> B 
1
git reset B

則 git 會將 log 中的 C, D, E 都清除
但檔案內容沒有任何變動, 因此會看到 C, D, E 修改的檔案處在 unstaged 階段(修改內容還在工作區)

然后你可以選擇(use "git checkout -- <file>..." to discard changes in working directory)完成回退

或者(use "git add <file>..." to update what will be committed) 放棄回退


若針對部分檔案還原可以用

1
git checkout [file path]

若要全部還原可用

1
git checkout -f

可以git reset --hard 直接回退,一步到位

結論

還沒 push 前, 個人傾向不產生太多 commit
因次我都會用 rebase -i 進行編修, 順便合併或reword 一些 commit

某個特殊情況, 例如發現某個 commit 裡面包含了不相干的檔案, 欲重新 commit 時
就會先用 rebase -i 把欲修改的 commit 換到後面(較新), 然後再用 reset 重新 stage + commit

 

=====================================

git revert 撤銷 某次操作,被撤銷的版本之前和之后的commit和history都會保留,並且把這次撤銷
作為一次最新的提交
    * git revert HEAD                  撤銷前一次 commit
    * git revert HEAD^               撤銷前前一次 commit
    * git revert commit_id (比如:fa042ce57ebbe5bb9c8db709f719cec2c58ee7ff)撤銷指定的版本,撤銷也會作為一次提交進行保存。
git revert是提交一個新的版本,將需要revert的版本的內容再反向修改回去
版本會遞增,不影響之前提交的內容

--------------------------------------------------------------------------------------------------------------------------------------------

git revert 和 git reset的區別 
1. git revert是用一次新的commit來回滾之前的commit,git reset是直接刪除指定的commit。 
2. 在回滾這一操作上看,效果差不多。但是在日后繼續merge以前的老版本時有區別。因為git revert是用一次逆向的commit“中和”之前的提交,因此日后合並老的branch時,導致這部分改變不會再次出現,但是git reset是之間把某些commit在某個branch上刪除,因而和老的branch再次merge時,這些被回滾的commit應該還會被引入。 
3. git reset 是把HEAD向后移動了一下,而git revert是HEAD繼續前進,只是新的commit的內容和要revert的內容正好相反,能夠抵消要被revert的內容。


免責聲明!

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



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