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