赞
踩
不管在工作还是个人开发的使用中,或多或少的我们都会接触到git的使用。但是,人非圣贤,总有犯错误的时候,写错代码,提交错误的代码也是在所难免的事情。
但是,不用着急!版本控制工具GIT在设计的时候就给开发者们设计了“后悔药”。当然,如果版本控制连这种功能都没有的话,也就可以淘汰了,好的,废话不多说,接下来就来介绍今天的主角:git reset
跟git revert
的使用以及区别!
我是因为在有一次工作的时候因为自己的粗心,在服务器上面修改代码准备验证,不小心将修改commit了(没有push到远程分支),然后。准备编译一个新的版本(编译版本的时候脚本会从远程pull代码),来确定问题的所在点,但是在远程分支上面,有人已经提交了问题所在的代码,这样导致我编译出来的版本因为我的本地commit导致了修改了正确的代码!因为已经commit了,脚本执行的git clean -df
也不能清除!当时也没有仔细的看编译log。后面就重新回退了代码,重新pull服务器的代码重新编译,也算是没有出什么大问题,后来,就对git的代码回退总结了一下,记录分享!
大家都知道,这两个语句都是用来回退代码的,可以回退我们之前的提交。语法的格式为:
git revert <commit_id>
git reset --hard <commit_id>
git reset [--soft] <commit_id>
虽然说git revert
跟git reset
都是用来回退代码的,但是真正在功能上面名副其实回退代码的应该是git reset
命令。当我们执行git revert
之后,其实整个分支的节奏是向前的,也就是说会产生一次新的提交,只不过这次提交是与对应<commit_id>改动相反的提交,而且一般来说revert是‘回退’一次提交,例如:
从上面的测试可以看出,结果完全符合我们的预期,所以说revert只是功能上面实现了看起来的‘回退’代码,实际是通过新的提交来覆盖之前的修改,接下来我们看看reset是如何操作的:
从上面的测试可以看出,结果完全符合我们的预期,所以说reset才是真正意义上面的代码回退,因为在执行过完git reset
指令之后我们用git log
去查看提交日志的时候,发现reset之前的提交已经不见了!实现了真正的代码回退,而且reset回退的是一个区间的的所有提交!
所以,如果我们要回退的是一个commit可能是很久以前的提交,那么肯定使用使用revert来进行操作的,但是如果我们是要回退最新一条的提交或者说是最新的提交到以前的一次提交,那么无疑选择reset是最便捷也更加优雅的方法!
讲到这里,可能就会有疑问,既然reset直接把提交都删除掉了,那如果我reset错误了一个,那不是闯下了滔天大祸了啊!哈哈,你错了,不要紧,git是可以强行去恢复reset的内容的!
看上面的测试,我在reset的时候添加了–hard的参数,因为快速的reset不经过staged暂存,这种情况的话需要强行才能恢复reset过的内容,但是,如果我们不添加参数或者说添加–soft参数(这两种情况类似)的话,git会把reset操作之后的内容暂存起来,修改如下:
在git reset --soft <commit_id>
之后的git status:
$ git status .
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
在这种情况下面,如果我们需要确认我们的reset操作的话,我们需要执行git reset HEAD <file>...
,执行完毕之后会变成下面不添加任何参数的这种情况,然后在执行git checkout .
来取消reset产生的修改操作。
在git reset <commit_id>
之后的状态:
resonLei@resonLei-PC MINGW64 /d/new_website_ssh/my_website (master) $ git reset 3c4abef54d2a63d0e3db440f6816085d27987b57 Unstaged changes after reset: M README.md resonLei@resonLei-PC MINGW64 /d/new_website_ssh/my_website (master) $ git status . On branch master Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch) Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a")
总结:通过操作的日志可以看出,我们在执行玩reset操作之后,git会认为我们的代码回到了reset对应<commit_id>版本,但是,因为本地的代码是reset之前最新的,所以如果不添加–hard参数的话,通过git status .
命令会出现有修改的情况,因为本地的代码跟reset之后的代码存在差异,系统没有直接删除这些内容,而是把这些内容当成了修改。当然,这个修改就是从reset对应<commit_id>reset之前的修改,如果你不需要reset的话,重新add然后commit就可以了,如果你依然执行reset之后的结果,执行git checkout .
就可以了,下面为执行不带参数后的reset之后的git diff
的结果:
resonLei@resonLei-PC MINGW64 /d/new_website_ssh/my_website (master)
$ git diff
diff --git a/README.md b/README.md
index 9eea745..7386e7f 100644
--- a/README.md
+++ b/README.md
@@ -21,4 +21,4 @@
### 聊天室模块
  使用中的建议聊天功能的实现,主要通过插入和读取数据库的建议操作,定时刷新来实现的,实现增量增加聊天数据!待学习完善!
-
+test git reset
可以看出来的是,本来test git reset这个字段在文件里面是存在的,在我reset到他不存在的地方的时候,git diff
显示我们添加了这个字段,表示我们现在git的版本里面已经没有了这一字段,但是系统目前认为你修改了,这个时候你可以采取对应的操作执行即可!
讲到这里,大概能能够了解这两个命令的基本操作了。但是可能你又会问,如果我reset成功了!也就是使用了–hard参数之后的效果。那么如果现在我发现自己弄错了需要怎么办呢?
最简单的方法就是如果你的远程分支的代码还没更改的话,直接使用git pull
就可以了!如果远程分支也跟本地修改的同步了,那么我们可以使用reset命令才重新的回退回去!但是重点就是你必须知道之前的commit id!知道的话直接reset回去就可以了,操作跟上面的基本一致!
PS.代码无价,不想加班,谨慎操作!如果有其他更好的方法回退,留言告知我吧!
如果要把本地reset之后的代码提交上去,如果直接使用git push
命令是不行的,会提示以下的错误,
resonLei@resonLei-PC MINGW64 /d/new_website_ssh/my_website (master)
$ git push
To git.oschina.net:Mr.Lei/my_website.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@git.oschina.net:Mr.Lei/my_website.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
这个时候我们需要在后面加上参数,例如:
git push --force
讲到这里基本上revert跟reset我的理解就到这里了。掌握了这两个命令,可以说在git的世界里面也就不怕什么,大不了就会回退呗!谁用谁知道~~~~
git show <commit_id> 查看对应的修改
git log -p filename 查看对应文件的修改历史日志
git chekcout . 撤销还没有添加的修改
git clean -df 清理工作目录,删除没有添加的文件等
git stash 暂存工作内容,可以把修改了没有commit的内容保存起来
git stash pop 等待工作完成之后可以把存起来的工作恢复
本文只代表个人见解,有很多不清楚和不正确的地方,欢迎纠正修改,共同进步!
我的个人网站,更多文章分享点击吧!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。