Git版本恢复命令reset和revert
git
reprint
2016-09-25

Git版本恢复命令reset和revert

放弃本地某个文件的修改:git checkout 文件名

一. 本地commit错误没有push到远程仓库

reset命令有3种方式:

  • git reset –mixed :此为默认方式,不带任何参数的git reset,即时这种方式,它回退 到某个版本,只保留源码,回退commit和index信息
  • git reset –soft :回退到某个版本,只回退了commit的信息,不会恢复到index file一 级。如果还要提交,直接commit即可
  • git reset –hard :彻底回退到某个版本,本地的源码也会变为上一个版本的内容

以下是一些reset的示例:

回退所有内容到上一个版本(HEAD回退add的版本):

git reset HEAD^

回退a.py这个文件的版本到上一个版本:

git reset HEAD^ a.py

向前回退到第3个版本:

git reset –soft HEAD~3

将本地的状态回退到和远程的一样 :

git reset –hard origin/master

回退到某个版本(–hard回退commit的版本) ,使用 git log 查询提交日志

  1. git reset 057d
  2. git reset –hard 057d

回退到上一次提交的状态,按照某一次的commit完全反向的进行一次commit:

git revert HEAD

二. 如果我们某次修改了某些内容,已经commit到本地仓库,而且已经push到远程仓库了

这种情况下,我们想把本地和远程仓库都回退到某个版本,该怎么做呢?

前面讲到的 git reset 只是在本地仓库中回退版本,而远程仓库的版本不会变化

这样,即时本地 reset 了,但如果再 git pull , 那么,远程仓库的内容又会和本地之前版本的内容进行merge

这并不是我们想要的东西,这时可以有2种办法来解决这个问题:

直接在远程server的仓库目录下,执行

git reset –soft 10efa

来回退。注意:在远程不能使用mixed或hard参数

在本地直接把远程的master分支给删除,然后再把reset后的分支内容给push上去,如下:

新建old_master分支做备份:

git branch old_master

push到远程:

git push origin old_master:old_master

本地仓库回退到某个版本:

git reset –hard bae168

删除远程的master分支:

git push origin :master

重新创建master分支:

git push origin master

在删除远程master分支时,可能会有问题,见下:

$ git push origin :master

error: By default, deleting the current branch is denied, because the next
error: 'git clone' won't result in any file checked out, causing confusion.
error:
error: You can set 'receive.denyDeleteCurrent' configuration variable to
error: 'warn' or 'ignore' in the remote repository to allow deleting the
error: current branch, with or without a warning message.
error:
error: To squelch this message, you can set it to 'refuse'.
error: refusing to delete the current branch: refs/heads/master
To git@xx.sohu.com:gitosis_test
 ! [remote rejected] master (deletion of the current branch prohibited)
error: failed to push some refs to 'git@xx.sohu.com:gitosis_test'
这时需要在远程仓库目录下,设置git的receive.denyDeleteCurrent参数

git receive.denyDeleteCurrent warn

然后,就可以删除远程的master分支了

虽然说有以上2种方法可以回退远程分支的版本,但这2种方式,都挺危险的,需要谨慎操作……

三. git revert

对于已经把代码push到远程仓库,你回退本地代码其实也想同时回退线上代码,回滚到某个指 定的版本,线上,线下代码保持一致.你要用到下面的命令

revert

git revert 用于反转提交,执行revert命令时要求工作树必须是干净的.

git revert 用一个新提交来消除一个历史提交所做的任何修改.

revert 之后你的本地代码会回滚到指定的历史版本,这时你再 git push 既可以把线上的代 码更新.(这里不会像reset造成冲突的问题)

revert 使用,需要先找到你想回滚版本唯一的 commit 标识代码,可以用 git log 或者在 adgit搭建的web环境历史提交记录里查看.

git revert c011eb3c20ba6fb38cc94fe5a8dda366a3990c61

通常,前几位即可

git revert c011eb3

git revert 是用一次新的commit来回滚之前的 commitgit reset 是直接删除指定的 commit

看似达到的效果是一样的,其实完全不同.

  • 第一: 上面我们说的如果你已经push到线上代码库, reset 删除指定commit以后,你git push可能导致一大堆冲突.但是revert 并不会.
  • 第二: 如果在日后现有分支和历史分支需要合并的时候,reset 恢复部分的代码依然会出 现在历史分支里.但是revert 方向提交的commit 并不会出现在历史分支里.
  • 第三: reset 是在正常的commit历史中,删除了指定的commit,这时 HEAD 是向后移动了, 而 revert 是在正常的commit历史中再commit一次,只不过是反向提交,他的 HEAD 是一直 向前的.
其它文章